aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD9
-rw-r--r--Makefile2
-rw-r--r--binding.gyp1
-rw-r--r--build.yaml3
-rw-r--r--doc/grpc-auth-support.md289
-rw-r--r--gRPC.podspec5
-rw-r--r--include/grpc/support/slice.h3
-rw-r--r--src/core/census/grpc_filter.c18
-rw-r--r--src/core/channel/channel_stack.c2
-rw-r--r--src/core/channel/channel_stack.h2
-rw-r--r--src/core/channel/client_channel.c3
-rw-r--r--src/core/channel/client_uchannel.c10
-rw-r--r--src/core/channel/compress_filter.c74
-rw-r--r--src/core/channel/http_client_filter.c98
-rw-r--r--src/core/channel/http_server_filter.c102
-rw-r--r--src/core/client_config/subchannel.c11
-rw-r--r--src/core/client_config/subchannel.h5
-rw-r--r--src/core/compression/algorithm.c50
-rw-r--r--src/core/compression/algorithm_metadata.h53
-rw-r--r--src/core/iomgr/fd_posix.c17
-rw-r--r--src/core/iomgr/fd_posix.h4
-rw-r--r--src/core/iomgr/tcp_client_posix.c4
-rw-r--r--src/core/iomgr/tcp_posix.c16
-rw-r--r--src/core/iomgr/tcp_posix.h6
-rw-r--r--src/core/iomgr/tcp_server_posix.c2
-rw-r--r--src/core/iomgr/udp_server.c2
-rw-r--r--src/core/iomgr/workqueue_posix.c2
-rw-r--r--src/core/security/client_auth_filter.c31
-rw-r--r--src/core/security/server_auth_filter.c2
-rw-r--r--src/core/security/server_secure_chttp2.c10
-rw-r--r--src/core/support/slice.c15
-rw-r--r--src/core/surface/call.c57
-rw-r--r--src/core/surface/channel.c115
-rw-r--r--src/core/surface/channel.h11
-rw-r--r--src/core/surface/channel_create.c17
-rw-r--r--src/core/surface/init.c2
-rw-r--r--src/core/surface/lame_client.c15
-rw-r--r--src/core/surface/secure_channel_create.c16
-rw-r--r--src/core/surface/server.c21
-rw-r--r--src/core/surface/server.h2
-rw-r--r--src/core/surface/server_chttp2.c9
-rw-r--r--src/core/transport/chttp2/hpack_encoder.c10
-rw-r--r--src/core/transport/chttp2/hpack_encoder.h8
-rw-r--r--src/core/transport/chttp2/hpack_parser.c26
-rw-r--r--src/core/transport/chttp2/hpack_parser.h3
-rw-r--r--src/core/transport/chttp2/hpack_table.c7
-rw-r--r--src/core/transport/chttp2/hpack_table.h3
-rw-r--r--src/core/transport/chttp2/internal.h4
-rw-r--r--src/core/transport/chttp2/parsing.c17
-rw-r--r--src/core/transport/chttp2_transport.c37
-rw-r--r--src/core/transport/chttp2_transport.h2
-rw-r--r--src/core/transport/metadata.c578
-rw-r--r--src/core/transport/metadata.h42
-rw-r--r--src/core/transport/static_metadata.c157
-rw-r--r--src/core/transport/static_metadata.h402
-rw-r--r--src/ruby/ext/grpc/extconf.rb4
-rw-r--r--test/core/bad_client/bad_client.c11
-rw-r--r--test/core/channel/channel_stack_test.c9
-rw-r--r--test/core/compression/compression_test.c3
-rw-r--r--test/core/compression/message_compress_test.c8
-rw-r--r--test/core/end2end/fixtures/h2_sockpair+trace.c27
-rw-r--r--test/core/end2end/fixtures/h2_sockpair.c27
-rw-r--r--test/core/end2end/fixtures/h2_sockpair_1byte.c27
-rw-r--r--test/core/end2end/fixtures/h2_uchannel.c19
-rw-r--r--test/core/iomgr/fd_posix_test.c8
-rw-r--r--test/core/iomgr/tcp_posix_test.c72
-rw-r--r--test/core/transport/chttp2/hpack_encoder_test.c9
-rw-r--r--test/core/transport/chttp2/hpack_parser_test.c15
-rw-r--r--test/core/transport/chttp2/hpack_table_test.c33
-rw-r--r--test/core/transport/metadata_test.c105
-rw-r--r--test/proto/metrics.proto4
-rwxr-xr-xtools/codegen/core/gen_static_metadata.py310
-rw-r--r--tools/doxygen/Doxyfile.core.internal3
-rwxr-xr-xtools/run_tests/post_tests_ruby.sh46
-rwxr-xr-xtools/run_tests/run_tests.py2
-rw-r--r--tools/run_tests/sources_and_headers.json10
-rw-r--r--vsprojects/vcxproj/grpc/grpc.vcxproj4
-rw-r--r--vsprojects/vcxproj/grpc/grpc.vcxproj.filters9
-rw-r--r--vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj4
-rw-r--r--vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters9
80 files changed, 1845 insertions, 1345 deletions
diff --git a/BUILD b/BUILD
index 2e2bd1fd3b..f1395dafd8 100644
--- a/BUILD
+++ b/BUILD
@@ -181,6 +181,7 @@ cc_library(
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
+ "src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",
@@ -263,6 +264,7 @@ cc_library(
"src/core/transport/connectivity_state.h",
"src/core/transport/metadata.h",
"src/core/transport/metadata_batch.h",
+ "src/core/transport/static_metadata.h",
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/census/aggregation.h",
@@ -413,6 +415,7 @@ cc_library(
"src/core/transport/connectivity_state.c",
"src/core/transport/metadata.c",
"src/core/transport/metadata_batch.c",
+ "src/core/transport/static_metadata.c",
"src/core/transport/transport.c",
"src/core/transport/transport_op_string.c",
"src/core/census/context.c",
@@ -474,6 +477,7 @@ cc_library(
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
+ "src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",
@@ -556,6 +560,7 @@ cc_library(
"src/core/transport/connectivity_state.h",
"src/core/transport/metadata.h",
"src/core/transport/metadata_batch.h",
+ "src/core/transport/static_metadata.h",
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/census/aggregation.h",
@@ -686,6 +691,7 @@ cc_library(
"src/core/transport/connectivity_state.c",
"src/core/transport/metadata.c",
"src/core/transport/metadata_batch.c",
+ "src/core/transport/static_metadata.c",
"src/core/transport/transport.c",
"src/core/transport/transport_op_string.c",
"src/core/census/context.c",
@@ -1219,6 +1225,7 @@ objc_library(
"src/core/transport/connectivity_state.c",
"src/core/transport/metadata.c",
"src/core/transport/metadata_batch.c",
+ "src/core/transport/static_metadata.c",
"src/core/transport/transport.c",
"src/core/transport/transport_op_string.c",
"src/core/census/context.c",
@@ -1277,6 +1284,7 @@ objc_library(
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
+ "src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",
@@ -1359,6 +1367,7 @@ objc_library(
"src/core/transport/connectivity_state.h",
"src/core/transport/metadata.h",
"src/core/transport/metadata_batch.h",
+ "src/core/transport/static_metadata.h",
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/census/aggregation.h",
diff --git a/Makefile b/Makefile
index 71d75e38f9..5363b4fe19 100644
--- a/Makefile
+++ b/Makefile
@@ -4644,6 +4644,7 @@ LIBGRPC_SRC = \
src/core/transport/connectivity_state.c \
src/core/transport/metadata.c \
src/core/transport/metadata_batch.c \
+ src/core/transport/static_metadata.c \
src/core/transport/transport.c \
src/core/transport/transport_op_string.c \
src/core/census/context.c \
@@ -4929,6 +4930,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/transport/connectivity_state.c \
src/core/transport/metadata.c \
src/core/transport/metadata_batch.c \
+ src/core/transport/static_metadata.c \
src/core/transport/transport.c \
src/core/transport/transport_op_string.c \
src/core/census/context.c \
diff --git a/binding.gyp b/binding.gyp
index 69d7ca723c..5205568739 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -297,6 +297,7 @@
'src/core/transport/connectivity_state.c',
'src/core/transport/metadata.c',
'src/core/transport/metadata_batch.c',
+ 'src/core/transport/static_metadata.c',
'src/core/transport/transport.c',
'src/core/transport/transport_op_string.c',
'src/core/census/context.c',
diff --git a/build.yaml b/build.yaml
index 82a023d269..f1e44fedd2 100644
--- a/build.yaml
+++ b/build.yaml
@@ -135,6 +135,7 @@ filegroups:
- src/core/client_config/subchannel_factory_decorators/add_channel_arg.h
- src/core/client_config/subchannel_factory_decorators/merge_channel_args.h
- src/core/client_config/uri_parser.h
+ - src/core/compression/algorithm_metadata.h
- src/core/compression/message_compress.h
- src/core/debug/trace.h
- src/core/httpcli/format_request.h
@@ -217,6 +218,7 @@ filegroups:
- src/core/transport/connectivity_state.h
- src/core/transport/metadata.h
- src/core/transport/metadata_batch.h
+ - src/core/transport/static_metadata.h
- src/core/transport/transport.h
- src/core/transport/transport_impl.h
src:
@@ -344,6 +346,7 @@ filegroups:
- src/core/transport/connectivity_state.c
- src/core/transport/metadata.c
- src/core/transport/metadata_batch.c
+ - src/core/transport/static_metadata.c
- src/core/transport/transport.c
- src/core/transport/transport_op_string.c
- name: grpc_test_util_base
diff --git a/doc/grpc-auth-support.md b/doc/grpc-auth-support.md
deleted file mode 100644
index b210ff1533..0000000000
--- a/doc/grpc-auth-support.md
+++ /dev/null
@@ -1,289 +0,0 @@
-#gRPC Authentication support
-
-gRPC is designed to plug-in a number of authentication mechanisms. This document
-provides a quick overview of the various auth mechanisms supported, discusses
-the API with some examples, and concludes with a discussion of extensibility.
-More documentation and examples are coming soon!
-
-## Supported auth mechanisms
-
-###SSL/TLS
-gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the
-server, and encrypt all the data exchanged between the client and the server.
-Optional mechanisms are available for clients to provide certificates to
-accomplish mutual authentication.
-
-###OAuth 2.0
-gRPC provides a generic mechanism (described below) to attach metadata to
-requests and responses. This mechanism can be used to attach OAuth 2.0 Access
-Tokens to RPCs being made at a client. Additional support for acquiring Access
-Tokens while accessing Google APIs through gRPC is provided for certain auth
-flows, demonstrated through code examples below.
-
-## API
-To reduce complexity and minimize API clutter, gRPC works with a unified concept
-of a Credentials object. Users construct gRPC credentials using corresponding
-bootstrap credentials (e.g., SSL client certs or Service Account Keys), and use
-the credentials while creating a gRPC channel to any server. Depending on the
-type of credential supplied, the channel uses the credentials during the initial
-SSL/TLS handshake with the server, or uses the credential to generate and
-attach Access Tokens to each request being made on the channel.
-
-###SSL/TLS for server authentication and encryption
-This is the simplest authentication scenario, where a client just wants to
-authenticate the server and encrypt all data.
-
-```cpp
-SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default
-// Create the credentials object by providing service account key in constructor
-std::shared_ptr<ChannelCredentials> creds = SslCredentials(ssl_opts);
-// Create a channel using the credentials created in the previous step
-std::shared_ptr<Channel> channel = CreateChannel(server_name, creds);
-// Create a stub on the channel
-std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
-// Make actual RPC calls on the stub.
-grpc::Status s = stub->sayHello(&context, *request, response);
-```
-
-For advanced use cases such as modifying the root CA or using client certs,
-the corresponding options can be set in the SslCredentialsOptions parameter
-passed to the factory method.
-
-
-###Authenticating with Google
-
-gRPC applications can use a simple API to create a credential that works in various deployment scenarios.
-
-```cpp
-std::shared_ptr<ChannelCredentials> creds = GoogleDefaultCredentials();
-// Create a channel, stub and make RPC calls (same as in the previous example)
-std::shared_ptr<Channel> channel = CreateChannel(server_name, creds);
-std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
-grpc::Status s = stub->sayHello(&context, *request, response);
-```
-
-This credential works for applications using Service Accounts as well as for
-applications running in [Google Compute Engine (GCE)](https://cloud.google.com/compute/). In the former case, the
-service account’s private keys are loaded from the file named in the environment
-variable `GOOGLE_APPLICATION_CREDENTIALS`. The
-keys are used to generate bearer tokens that are attached to each outgoing RPC
-on the corresponding channel.
-
-For applications running in GCE, a default service account and corresponding
-OAuth scopes can be configured during VM setup. At run-time, this credential
-handles communication with the authentication systems to obtain OAuth2 access
-tokens and attaches them to each outgoing RPC on the corresponding channel.
-Extending gRPC to support other authentication mechanisms
-The gRPC protocol is designed with a general mechanism for sending metadata
-associated with RPC. Clients can send metadata at the beginning of an RPC and
-servers can send back metadata at the beginning and end of the RPC. This
-provides a natural mechanism to support OAuth2 and other authentication
-mechanisms that need attach bearer tokens to individual request.
-
-In the simplest case, there is a single line of code required on the client
-to add a specific token as metadata to an RPC and a corresponding access on
-the server to retrieve this piece of metadata. The generation of the token
-on the client side and its verification at the server can be done separately.
-
-A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms.
-
-## Examples
-
-These authentication mechanisms will be available in all gRPC's supported languages.
-The following sections demonstrate how authentication and authorization features described above appear in each language: more languages are coming soon.
-
-###SSL/TLS for server authentication and encryption (Ruby)
-```ruby
-# Base case - No encryption
-stub = Helloworld::Greeter::Stub.new('localhost:50051')
-...
-
-# With server authentication SSL/TLS
-creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file
-stub = Helloworld::Greeter::Stub.new('localhost:50051', creds: creds)
-```
-
-###SSL/TLS for server authentication and encryption (C#)
-```csharp
-// Base case - No encryption
-var channel = new Channel("localhost:50051");
-var client = new Greeter.GreeterClient(channel);
-...
-
-// With server authentication SSL/TLS
-var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file
-var channel = new Channel("localhost:50051", credentials);
-var client = new Greeter.GreeterClient(channel);
-```
-
-###SSL/TLS for server authentication and encryption (Objective-C)
-
-The default for Objective-C is to use SSL/TLS, as that's the most common use case when accessing
-remote APIs.
-
-```objective-c
-// Base case - With server authentication SSL/TLS
-HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"localhost:50051"];
-// Same as using @"https://localhost:50051".
-...
-
-// No encryption
-HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"http://localhost:50051"];
-// Specifying the HTTP scheme explicitly forces no encryption.
-```
-
-###SSL/TLS for server authentication and encryption (Python)
-```python
-# Base case - No encryption
-stub = early_adopter_create_GreeterService_stub('localhost', 50051)
-...
-
-# With server authentication SSL/TLS
-stub = early_adopter_create_GreeterService_stub(
- 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read())
-...
-```
-n.b.: the beta API will look different
-
-###Authenticating with Google (Ruby)
-```ruby
-# Base case - No encryption/authorization
-stub = Helloworld::Greeter::Stub.new('localhost:50051')
-...
-
-# Authenticating with Google
-require 'googleauth' # from http://www.rubydoc.info/gems/googleauth/0.1.0
-...
-creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file
-scope = 'https://www.googleapis.com/auth/grpc-testing'
-authorization = Google::Auth.get_application_default(scope)
-stub = Helloworld::Greeter::Stub.new('localhost:50051',
- creds: creds,
- update_metadata: authorization.updater_proc)
-```
-
-###Authenticating with Google (Node.js)
-
-```node
-// Base case - No encryption/authorization
-var stub = new helloworld.Greeter('localhost:50051');
-...
-// Authenticating with Google
-var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library
-...
-var creds = grpc.Credentials.createSsl(load_certs); // load_certs typically loads a CA roots file
-var scope = 'https://www.googleapis.com/auth/grpc-testing';
-(new GoogleAuth()).getApplicationDefault(function(err, auth) {
- if (auth.createScopeRequired()) {
- auth = auth.createScoped(scope);
- }
- var stub = new helloworld.Greeter('localhost:50051',
- {credentials: creds},
- grpc.getGoogleAuthDelegate(auth));
-});
-```
-
-###Authenticating with Google (C#)
-```csharp
-// Base case - No encryption/authorization
-var channel = new Channel("localhost:50051");
-var client = new Greeter.GreeterClient(channel);
-...
-
-// Authenticating with Google
-using Grpc.Auth; // from Grpc.Auth NuGet package
-...
-var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file
-var channel = new Channel("localhost:50051", credentials);
-
-string scope = "https://www.googleapis.com/auth/grpc-testing";
-var authorization = GoogleCredential.GetApplicationDefault();
-if (authorization.IsCreateScopedRequired)
-{
- authorization = credential.CreateScoped(new[] { scope });
-}
-var client = new Greeter.GreeterClient(channel,
- new StubConfiguration(OAuth2InterceptorFactory.Create(credential)));
-```
-
-###Authenticating with Google (PHP)
-```php
-// Base case - No encryption/authorization
-$client = new helloworld\GreeterClient(
- new Grpc\BaseStub('localhost:50051', []));
-...
-
-// Authenticating with Google
-// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set
-$scope = "https://www.googleapis.com/auth/grpc-testing";
-$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope);
-$opts = [
- 'credentials' => Grpc\Credentials::createSsl(file_get_contents('ca.pem'));
- 'update_metadata' => $auth->getUpdateMetadataFunc(),
-];
-
-$client = new helloworld\GreeterClient(
- new Grpc\BaseStub('localhost:50051', $opts));
-
-```
-
-###Authenticating with Google (Objective-C)
-
-This example uses the [Google iOS Sign-In library](https://developers.google.com/identity/sign-in/ios/),
-but it's easily extrapolated to any other OAuth2 library.
-
-```objective-c
-// Base case - No authentication
-[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
- ...
-}];
-
-...
-
-// Authenticating with Google
-
-// When signing the user in, ask her for the relevant scopes.
-GIDSignIn.sharedInstance.scopes = @[@"https://www.googleapis.com/auth/grpc-testing"];
-
-...
-
-#import <ProtoRPC/ProtoRPC.h>
-
-// Create a not-yet-started RPC. We want to set the request headers on this object before starting
-// it.
-ProtoRPC *call =
- [client RPCToSayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
- ...
- }];
-
-// Set the access token to be used.
-NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken;
-call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]}];
-
-// Start the RPC.
-[call start];
-```
-
-You can see a working example app, with a more detailed explanation, [here](examples/objective-c/auth_sample).
-
-### Authenticating with Google (Python)
-```python
-# Base case - No encryption
-stub = early_adopter_create_GreeterService_stub('localhost', 50051)
-...
-
-# With server authentication SSL/TLS
-import oauth2client.client
-credentials = oauth2client.GoogleCredentials.get_application_default()
-scope = 'https://www.googleapis.com/auth/grpc-testing'
-scoped_credentials = credentials.create_scoped([scope])
-access_token = scoped_credentials.get_access_token().access_token
-metadata_transformer = (
- lambda x: [('Authorization', 'Bearer {}'.format(access_token))])
-
-stub = early_adopter_create_GreeterService_stub(
- 'localhost', 50051, secure=True, root_certificates=open('ca.pem').read(),
- metadata_transformer=metadata_transformer)
-...
-```
-n.b.: the beta API will look different
diff --git a/gRPC.podspec b/gRPC.podspec
index 279794378b..0262479f61 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -185,6 +185,7 @@ Pod::Spec.new do |s|
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.h',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.h',
'src/core/client_config/uri_parser.h',
+ 'src/core/compression/algorithm_metadata.h',
'src/core/compression/message_compress.h',
'src/core/debug/trace.h',
'src/core/httpcli/format_request.h',
@@ -267,6 +268,7 @@ Pod::Spec.new do |s|
'src/core/transport/connectivity_state.h',
'src/core/transport/metadata.h',
'src/core/transport/metadata_batch.h',
+ 'src/core/transport/static_metadata.h',
'src/core/transport/transport.h',
'src/core/transport/transport_impl.h',
'src/core/census/aggregation.h',
@@ -424,6 +426,7 @@ Pod::Spec.new do |s|
'src/core/transport/connectivity_state.c',
'src/core/transport/metadata.c',
'src/core/transport/metadata_batch.c',
+ 'src/core/transport/static_metadata.c',
'src/core/transport/transport.c',
'src/core/transport/transport_op_string.c',
'src/core/census/context.c',
@@ -484,6 +487,7 @@ Pod::Spec.new do |s|
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.h',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.h',
'src/core/client_config/uri_parser.h',
+ 'src/core/compression/algorithm_metadata.h',
'src/core/compression/message_compress.h',
'src/core/debug/trace.h',
'src/core/httpcli/format_request.h',
@@ -566,6 +570,7 @@ Pod::Spec.new do |s|
'src/core/transport/connectivity_state.h',
'src/core/transport/metadata.h',
'src/core/transport/metadata_batch.h',
+ 'src/core/transport/static_metadata.h',
'src/core/transport/transport.h',
'src/core/transport/transport_impl.h',
'src/core/census/aggregation.h',
diff --git a/include/grpc/support/slice.h b/include/grpc/support/slice.h
index 3abb1b7ca1..507cb19f64 100644
--- a/include/grpc/support/slice.h
+++ b/include/grpc/support/slice.h
@@ -144,6 +144,9 @@ gpr_slice gpr_slice_from_copied_string(const char *source);
memcpy(slice->data, source, len); */
gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len);
+/* Create a slice pointing to constant memory */
+gpr_slice gpr_slice_from_static_string(const char *source);
+
/* 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.
diff --git a/src/core/census/grpc_filter.c b/src/core/census/grpc_filter.c
index daa1a7ac61..61a95ec765 100644
--- a/src/core/census/grpc_filter.c
+++ b/src/core/census/grpc_filter.c
@@ -36,16 +36,18 @@
#include <stdio.h>
#include <string.h>
-#include "src/core/channel/channel_stack.h"
-#include "src/core/channel/noop_filter.h"
-#include "src/core/statistics/census_interface.h"
-#include "src/core/statistics/census_rpc_stats.h"
#include <grpc/census.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/slice.h>
#include <grpc/support/time.h>
+#include "src/core/channel/channel_stack.h"
+#include "src/core/channel/noop_filter.h"
+#include "src/core/statistics/census_interface.h"
+#include "src/core/statistics/census_rpc_stats.h"
+#include "src/core/transport/static_metadata.h"
+
typedef struct call_data {
census_op_id op_id;
census_context *ctxt;
@@ -59,7 +61,7 @@ typedef struct call_data {
} call_data;
typedef struct channel_data {
- grpc_mdstr *path_str; /* pointer to meta data str with key == ":path" */
+ gpr_uint8 unused;
} channel_data;
static void extract_and_annotate_method_tag(grpc_metadata_batch *md,
@@ -67,7 +69,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 == chand->path_str) {
+ if (m->md->key == GRPC_MDSTR_PATH) {
gpr_log(GPR_DEBUG, "%s",
(const char *)GPR_SLICE_START_PTR(m->md->value->slice));
/* Add method tag here */
@@ -161,16 +163,12 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element_args *args) {
channel_data *chand = elem->channel_data;
GPR_ASSERT(chand != NULL);
- chand->path_str = grpc_mdstr_from_string(args->metadata_context, ":path");
}
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
channel_data *chand = elem->channel_data;
GPR_ASSERT(chand != NULL);
- if (chand->path_str != NULL) {
- GRPC_MDSTR_UNREF(chand->path_str);
- }
}
const grpc_channel_filter grpc_client_census_filter = {
diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c
index 02e33a09ab..7f7fbf420f 100644
--- a/src/core/channel/channel_stack.c
+++ b/src/core/channel/channel_stack.c
@@ -105,7 +105,6 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx,
const grpc_channel_filter **filters,
size_t filter_count, grpc_channel *master,
const grpc_channel_args *channel_args,
- grpc_mdctx *metadata_context,
grpc_channel_stack *stack) {
size_t call_size =
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
@@ -125,7 +124,6 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx,
for (i = 0; i < filter_count; i++) {
args.master = master;
args.channel_args = channel_args;
- args.metadata_context = metadata_context;
args.is_first = i == 0;
args.is_last = i == (filter_count - 1);
elems[i].filter = filters[i];
diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h
index 5d33ab5b42..1db12ead7e 100644
--- a/src/core/channel/channel_stack.h
+++ b/src/core/channel/channel_stack.h
@@ -54,7 +54,6 @@ typedef struct grpc_call_element grpc_call_element;
typedef struct {
grpc_channel *master;
const grpc_channel_args *channel_args;
- grpc_mdctx *metadata_context;
int is_first;
int is_last;
} grpc_channel_element_args;
@@ -180,7 +179,6 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx,
const grpc_channel_filter **filters,
size_t filter_count, grpc_channel *master,
const grpc_channel_args *args,
- grpc_mdctx *metadata_context,
grpc_channel_stack *stack);
/* Destroy a channel stack */
void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index 16d91d4277..020138bf15 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -55,8 +55,6 @@
typedef grpc_subchannel_call_holder call_data;
typedef struct client_channel_channel_data {
- /** metadata context for this channel */
- grpc_mdctx *mdctx;
/** resolver for this channel */
grpc_resolver *resolver;
/** have we started resolving this channel */
@@ -387,7 +385,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
gpr_mu_init(&chand->mu_config);
- chand->mdctx = args->metadata_context;
chand->master = args->master;
grpc_pollset_set_init(&chand->pollset_set);
grpc_closure_init(&chand->on_config_changed, cc_on_config_changed, chand);
diff --git a/src/core/channel/client_uchannel.c b/src/core/channel/client_uchannel.c
index ec6b02381a..456ffb7371 100644
--- a/src/core/channel/client_uchannel.c
+++ b/src/core/channel/client_uchannel.c
@@ -54,9 +54,6 @@
* load-balancing mechanisms meant for communication from within the core. */
typedef struct client_uchannel_channel_data {
- /** metadata context for this channel */
- grpc_mdctx *mdctx;
-
/** master channel - the grpc_channel instance that ultimately owns
this channel_data via its channel stack.
We occasionally use this to bump the refcount on the master channel
@@ -161,7 +158,6 @@ static void cuc_init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_closure_init(&chand->connectivity_cb, monitor_subchannel, chand);
GPR_ASSERT(args->is_last);
GPR_ASSERT(elem->filter == &grpc_client_uchannel_filter);
- chand->mdctx = args->metadata_context;
chand->master = args->master;
grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
"client_uchannel");
@@ -252,13 +248,11 @@ grpc_channel *grpc_client_uchannel_create(grpc_subchannel *subchannel,
grpc_channel *channel = NULL;
#define MAX_FILTERS 3
const grpc_channel_filter *filters[MAX_FILTERS];
- grpc_mdctx *mdctx = grpc_subchannel_get_mdctx(subchannel);
grpc_channel *master = grpc_subchannel_get_master(subchannel);
char *target = grpc_channel_get_target(master);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
size_t n = 0;
- grpc_mdctx_ref(mdctx);
if (grpc_channel_args_is_census_enabled(args)) {
filters[n++] = &grpc_client_census_filter;
}
@@ -266,8 +260,8 @@ grpc_channel *grpc_client_uchannel_create(grpc_subchannel *subchannel,
filters[n++] = &grpc_client_uchannel_filter;
GPR_ASSERT(n <= MAX_FILTERS);
- channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
- args, mdctx, 1);
+ channel =
+ grpc_channel_create_from_filters(&exec_ctx, target, filters, n, args, 1);
gpr_free(target);
return channel;
diff --git a/src/core/channel/compress_filter.c b/src/core/channel/compress_filter.c
index f23d8052f3..fc8b425e47 100644
--- a/src/core/channel/compress_filter.c
+++ b/src/core/channel/compress_filter.c
@@ -42,8 +42,10 @@
#include "src/core/channel/compress_filter.h"
#include "src/core/channel/channel_args.h"
#include "src/core/profiling/timers.h"
+#include "src/core/compression/algorithm_metadata.h"
#include "src/core/compression/message_compress.h"
#include "src/core/support/string.h"
+#include "src/core/transport/static_metadata.h"
typedef struct call_data {
gpr_slice_buffer slices; /**< Buffers up input slices to be compressed */
@@ -67,20 +69,12 @@ typedef struct call_data {
} call_data;
typedef struct channel_data {
- /** Metadata key for the incoming (requested) compression algorithm */
- grpc_mdstr *mdstr_request_compression_algorithm_key;
- /** Metadata key for the outgoing (used) compression algorithm */
- grpc_mdstr *mdstr_outgoing_compression_algorithm_key;
- /** Metadata key for the accepted encodings */
- grpc_mdstr *mdstr_compression_capabilities_key;
- /** Precomputed metadata elements for all available compression algorithms */
- grpc_mdelem *mdelem_compression_algorithms[GRPC_COMPRESS_ALGORITHMS_COUNT];
- /** Precomputed metadata elements for the accepted encodings */
- grpc_mdelem *mdelem_accept_encoding;
/** The default, channel-level, compression algorithm */
grpc_compression_algorithm default_compression_algorithm;
/** Compression options for the channel */
grpc_compression_options compression_options;
+ /** Supported compression algorithms */
+ gpr_uint32 supported_compression_algorithms;
} channel_data;
/** For each \a md element from the incoming metadata, filter out the entry for
@@ -91,7 +85,7 @@ static grpc_mdelem *compression_md_filter(void *user_data, grpc_mdelem *md) {
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
- if (md->key == channeld->mdstr_request_compression_algorithm_key) {
+ 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),
&calld->compression_algorithm)) {
@@ -147,14 +141,13 @@ static void process_send_initial_metadata(
/* hint compression algorithm */
grpc_metadata_batch_add_tail(
initial_metadata, &calld->compression_algorithm_storage,
- GRPC_MDELEM_REF(
- channeld
- ->mdelem_compression_algorithms[calld->compression_algorithm]));
+ grpc_compression_encoding_mdelem(calld->compression_algorithm));
/* convey supported compression algorithms */
- grpc_metadata_batch_add_tail(
- initial_metadata, &calld->accept_encoding_storage,
- GRPC_MDELEM_REF(channeld->mdelem_accept_encoding));
+ grpc_metadata_batch_add_tail(initial_metadata,
+ &calld->accept_encoding_storage,
+ GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(
+ channeld->supported_compression_algorithms));
}
static void continue_send_message(grpc_exec_ctx *exec_ctx,
@@ -266,10 +259,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element_args *args) {
channel_data *channeld = elem->channel_data;
grpc_compression_algorithm algo_idx;
- const char *supported_algorithms_names[GRPC_COMPRESS_ALGORITHMS_COUNT - 1];
- size_t supported_algorithms_idx = 0;
- char *accept_encoding_str;
- size_t accept_encoding_str_len;
grpc_compression_options_init(&channeld->compression_options);
channeld->compression_options.enabled_algorithms_bitset =
@@ -284,61 +273,22 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
channeld->compression_options.default_compression_algorithm =
channeld->default_compression_algorithm;
- channeld->mdstr_request_compression_algorithm_key = grpc_mdstr_from_string(
- args->metadata_context, GRPC_COMPRESS_REQUEST_ALGORITHM_KEY);
-
- channeld->mdstr_outgoing_compression_algorithm_key =
- grpc_mdstr_from_string(args->metadata_context, "grpc-encoding");
-
- channeld->mdstr_compression_capabilities_key =
- grpc_mdstr_from_string(args->metadata_context, "grpc-accept-encoding");
-
+ channeld->supported_compression_algorithms = 0;
for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
- char *algorithm_name;
/* skip disabled algorithms */
if (grpc_compression_options_is_algorithm_enabled(
&channeld->compression_options, algo_idx) == 0) {
continue;
}
- GPR_ASSERT(grpc_compression_algorithm_name(algo_idx, &algorithm_name) != 0);
- channeld->mdelem_compression_algorithms[algo_idx] =
- grpc_mdelem_from_metadata_strings(
- args->metadata_context,
- GRPC_MDSTR_REF(channeld->mdstr_outgoing_compression_algorithm_key),
- grpc_mdstr_from_string(args->metadata_context, algorithm_name));
- if (algo_idx > 0) {
- supported_algorithms_names[supported_algorithms_idx++] = algorithm_name;
- }
+ channeld->supported_compression_algorithms |= 1u << algo_idx;
}
- /* TODO(dgq): gpr_strjoin_sep could be made to work with statically allocated
- * arrays, as to avoid the heap allocs */
- accept_encoding_str =
- gpr_strjoin_sep(supported_algorithms_names, supported_algorithms_idx, ",",
- &accept_encoding_str_len);
-
- channeld->mdelem_accept_encoding = grpc_mdelem_from_metadata_strings(
- args->metadata_context,
- GRPC_MDSTR_REF(channeld->mdstr_compression_capabilities_key),
- grpc_mdstr_from_string(args->metadata_context, accept_encoding_str));
- gpr_free(accept_encoding_str);
-
GPR_ASSERT(!args->is_last);
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
- channel_data *channeld = elem->channel_data;
- grpc_compression_algorithm algo_idx;
-
- GRPC_MDSTR_UNREF(channeld->mdstr_request_compression_algorithm_key);
- GRPC_MDSTR_UNREF(channeld->mdstr_outgoing_compression_algorithm_key);
- GRPC_MDSTR_UNREF(channeld->mdstr_compression_capabilities_key);
- for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
- GRPC_MDELEM_UNREF(channeld->mdelem_compression_algorithms[algo_idx]);
- }
- GRPC_MDELEM_UNREF(channeld->mdelem_accept_encoding);
}
const grpc_channel_filter grpc_compress_filter = {
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c
index 3a0f68f30f..b9a30cdaf2 100644
--- a/src/core/channel/http_client_filter.c
+++ b/src/core/channel/http_client_filter.c
@@ -37,6 +37,7 @@
#include <grpc/support/string_util.h>
#include "src/core/support/string.h"
#include "src/core/profiling/timers.h"
+#include "src/core/transport/static_metadata.h"
typedef struct call_data {
grpc_linked_mdelem method;
@@ -57,12 +58,7 @@ typedef struct call_data {
} call_data;
typedef struct channel_data {
- grpc_mdelem *te_trailers;
- grpc_mdelem *method;
- grpc_mdelem *scheme;
- grpc_mdelem *content_type;
- grpc_mdelem *status;
- /** complete user agent mdelem */
+ grpc_mdelem *static_scheme;
grpc_mdelem *user_agent;
} channel_data;
@@ -73,14 +69,12 @@ typedef struct {
static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) {
client_recv_filter_args *a = user_data;
- grpc_call_element *elem = a->elem;
- channel_data *channeld = elem->channel_data;
- if (md == channeld->status) {
+ if (md == GRPC_MDELEM_STATUS_200) {
return NULL;
- } else if (md->key == channeld->status->key) {
- grpc_call_element_send_cancel(a->exec_ctx, elem);
+ } else if (md->key == GRPC_MDSTR_STATUS) {
+ grpc_call_element_send_cancel(a->exec_ctx, a->elem);
return NULL;
- } else if (md->key == channeld->content_type->key) {
+ } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
return NULL;
}
return md;
@@ -98,14 +92,12 @@ static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, int success) {
}
static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
- grpc_call_element *elem = user_data;
- channel_data *channeld = elem->channel_data;
/* eat the things we'd like to set ourselves */
- if (md->key == channeld->method->key) return NULL;
- if (md->key == channeld->scheme->key) return NULL;
- if (md->key == channeld->te_trailers->key) return NULL;
- if (md->key == channeld->content_type->key) return NULL;
- if (md->key == channeld->user_agent->key) return NULL;
+ 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;
return md;
}
@@ -120,14 +112,14 @@ static void hc_mutate_op(grpc_call_element *elem,
/* Send : prefixed headers, which have to be before any application
layer headers. */
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
- GRPC_MDELEM_REF(channeld->method));
+ GRPC_MDELEM_METHOD_POST);
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme,
- GRPC_MDELEM_REF(channeld->scheme));
+ channeld->static_scheme);
grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers,
- GRPC_MDELEM_REF(channeld->te_trailers));
- grpc_metadata_batch_add_tail(op->send_initial_metadata,
- &calld->content_type,
- GRPC_MDELEM_REF(channeld->content_type));
+ GRPC_MDELEM_TE_TRAILERS);
+ grpc_metadata_batch_add_tail(
+ op->send_initial_metadata, &calld->content_type,
+ GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC);
grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->user_agent,
GRPC_MDELEM_REF(channeld->user_agent));
}
@@ -162,21 +154,28 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem) {}
-static const char *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};
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) {
- return args->args[i].value.string;
+ 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)) {
+ return valid_schemes[j];
+ }
+ }
}
}
}
- return "http";
+ return GRPC_MDELEM_SCHEME_HTTP;
}
-static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx,
- const grpc_channel_args *args) {
+static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args) {
gpr_strvec v;
size_t i;
int is_first = 1;
@@ -218,7 +217,7 @@ static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx,
tmp = gpr_strvec_flatten(&v, NULL);
gpr_strvec_destroy(&v);
- result = grpc_mdstr_from_string(mdctx, tmp);
+ result = grpc_mdstr_from_string(tmp);
gpr_free(tmp);
return result;
@@ -228,43 +227,18 @@ static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx,
static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
- /* grab pointers to our data from the channel element */
- channel_data *channeld = elem->channel_data;
-
- /* The first and the last filters tend to be implemented differently to
- handle the case that there's no 'next' filter to call on the up or down
- path */
+ channel_data *chand = elem->channel_data;
GPR_ASSERT(!args->is_last);
-
- /* initialize members */
- channeld->te_trailers =
- grpc_mdelem_from_strings(args->metadata_context, "te", "trailers");
- channeld->method =
- grpc_mdelem_from_strings(args->metadata_context, ":method", "POST");
- channeld->scheme = grpc_mdelem_from_strings(
- args->metadata_context, ":scheme", scheme_from_args(args->channel_args));
- channeld->content_type = grpc_mdelem_from_strings(
- args->metadata_context, "content-type", "application/grpc");
- channeld->status =
- grpc_mdelem_from_strings(args->metadata_context, ":status", "200");
- channeld->user_agent = grpc_mdelem_from_metadata_strings(
- args->metadata_context,
- grpc_mdstr_from_string(args->metadata_context, "user-agent"),
- user_agent_from_args(args->metadata_context, args->channel_args));
+ chand->static_scheme = scheme_from_args(args->channel_args);
+ chand->user_agent = grpc_mdelem_from_metadata_strings(
+ GRPC_MDSTR_USER_AGENT, user_agent_from_args(args->channel_args));
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
- /* grab pointers to our data from the channel element */
- channel_data *channeld = elem->channel_data;
-
- GRPC_MDELEM_UNREF(channeld->te_trailers);
- GRPC_MDELEM_UNREF(channeld->method);
- GRPC_MDELEM_UNREF(channeld->scheme);
- GRPC_MDELEM_UNREF(channeld->content_type);
- GRPC_MDELEM_UNREF(channeld->status);
- GRPC_MDELEM_UNREF(channeld->user_agent);
+ channel_data *chand = elem->channel_data;
+ GRPC_MDELEM_UNREF(chand->user_agent);
}
const grpc_channel_filter grpc_http_client_filter = {
diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c
index 2adfe2bb61..c1645c2ba0 100644
--- a/src/core/channel/http_server_filter.c
+++ b/src/core/channel/http_server_filter.c
@@ -37,6 +37,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/profiling/timers.h"
+#include "src/core/transport/static_metadata.h"
typedef struct call_data {
gpr_uint8 seen_path;
@@ -57,22 +58,7 @@ typedef struct call_data {
grpc_closure hs_on_recv;
} call_data;
-typedef struct channel_data {
- grpc_mdelem *te_trailers;
- grpc_mdelem *method_post;
- grpc_mdelem *http_scheme;
- grpc_mdelem *https_scheme;
- /* TODO(klempner): Remove this once we stop using it */
- grpc_mdelem *grpc_scheme;
- grpc_mdelem *content_type;
- grpc_mdelem *status_ok;
- grpc_mdelem *status_not_found;
- grpc_mdstr *path_key;
- grpc_mdstr *authority_key;
- grpc_mdstr *host_key;
-
- grpc_mdctx *mdctx;
-} channel_data;
+typedef struct channel_data { gpr_uint8 unused; } channel_data;
typedef struct {
grpc_call_element *elem;
@@ -82,25 +68,24 @@ typedef struct {
static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
server_filter_args *a = user_data;
grpc_call_element *elem = a->elem;
- channel_data *channeld = elem->channel_data;
call_data *calld = elem->call_data;
/* Check if it is one of the headers we care about. */
- if (md == channeld->te_trailers || md == channeld->method_post ||
- md == channeld->http_scheme || md == channeld->https_scheme ||
- md == channeld->grpc_scheme || md == channeld->content_type) {
+ if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST ||
+ md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS ||
+ md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
/* swallow it */
- if (md == channeld->method_post) {
+ if (md == GRPC_MDELEM_METHOD_POST) {
calld->seen_post = 1;
- } else if (md->key == channeld->http_scheme->key) {
+ } else if (md->key == GRPC_MDSTR_SCHEME) {
calld->seen_scheme = 1;
- } else if (md == channeld->te_trailers) {
+ } else if (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 == channeld->content_type->key) {
+ } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
if (strncmp(grpc_mdstr_as_c_string(md->value), "application/grpc+", 17) ==
0) {
/* Although the C implementation doesn't (currently) generate them,
@@ -112,12 +97,11 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
/* 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",
- channeld->content_type->key);
+ grpc_mdstr_as_c_string(md->value));
}
return NULL;
- } else if (md->key == channeld->te_trailers->key ||
- md->key == channeld->method_post->key ||
- md->key == channeld->http_scheme->key) {
+ } 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));
/* swallow it and error everything out. */
@@ -125,22 +109,21 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
on the wire here. */
grpc_call_element_send_cancel(a->exec_ctx, elem);
return NULL;
- } else if (md->key == channeld->path_key) {
+ } else if (md->key == GRPC_MDSTR_PATH) {
if (calld->seen_path) {
gpr_log(GPR_ERROR, "Received :path twice");
return NULL;
}
calld->seen_path = 1;
return md;
- } else if (md->key == channeld->authority_key) {
+ } else if (md->key == GRPC_MDSTR_AUTHORITY) {
calld->seen_authority = 1;
return md;
- } else if (md->key == channeld->host_key) {
+ } else if (md->key == GRPC_MDSTR_HOST) {
/* translate host to :authority since :authority may be
omitted */
grpc_mdelem *authority = grpc_mdelem_from_metadata_strings(
- channeld->mdctx, GRPC_MDSTR_REF(channeld->authority_key),
- GRPC_MDSTR_REF(md->value));
+ GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
GRPC_MDELEM_UNREF(md);
calld->seen_authority = 1;
return authority;
@@ -191,15 +174,14 @@ static void hs_mutate_op(grpc_call_element *elem,
grpc_transport_stream_op *op) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
- channel_data *channeld = elem->channel_data;
if (op->send_initial_metadata != NULL && !calld->sent_status) {
calld->sent_status = 1;
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->status,
- GRPC_MDELEM_REF(channeld->status_ok));
- grpc_metadata_batch_add_tail(op->send_initial_metadata,
- &calld->content_type,
- GRPC_MDELEM_REF(channeld->content_type));
+ GRPC_MDELEM_STATUS_200);
+ grpc_metadata_batch_add_tail(
+ op->send_initial_metadata, &calld->content_type,
+ GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC);
}
if (op->recv_initial_metadata) {
@@ -238,56 +220,12 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
- /* grab pointers to our data from the channel element */
- channel_data *channeld = elem->channel_data;
-
- /* The first and the last filters tend to be implemented differently to
- handle the case that there's no 'next' filter to call on the up or down
- path */
GPR_ASSERT(!args->is_last);
-
- /* initialize members */
- channeld->te_trailers =
- grpc_mdelem_from_strings(args->metadata_context, "te", "trailers");
- channeld->status_ok =
- grpc_mdelem_from_strings(args->metadata_context, ":status", "200");
- channeld->status_not_found =
- grpc_mdelem_from_strings(args->metadata_context, ":status", "404");
- channeld->method_post =
- grpc_mdelem_from_strings(args->metadata_context, ":method", "POST");
- channeld->http_scheme =
- grpc_mdelem_from_strings(args->metadata_context, ":scheme", "http");
- channeld->https_scheme =
- grpc_mdelem_from_strings(args->metadata_context, ":scheme", "https");
- channeld->grpc_scheme =
- grpc_mdelem_from_strings(args->metadata_context, ":scheme", "grpc");
- channeld->path_key = grpc_mdstr_from_string(args->metadata_context, ":path");
- channeld->authority_key =
- grpc_mdstr_from_string(args->metadata_context, ":authority");
- channeld->host_key = grpc_mdstr_from_string(args->metadata_context, "host");
- channeld->content_type = grpc_mdelem_from_strings(
- args->metadata_context, "content-type", "application/grpc");
-
- channeld->mdctx = args->metadata_context;
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
- /* grab pointers to our data from the channel element */
- channel_data *channeld = elem->channel_data;
-
- GRPC_MDELEM_UNREF(channeld->te_trailers);
- GRPC_MDELEM_UNREF(channeld->status_ok);
- GRPC_MDELEM_UNREF(channeld->status_not_found);
- GRPC_MDELEM_UNREF(channeld->method_post);
- GRPC_MDELEM_UNREF(channeld->http_scheme);
- GRPC_MDELEM_UNREF(channeld->https_scheme);
- GRPC_MDELEM_UNREF(channeld->grpc_scheme);
- GRPC_MDELEM_UNREF(channeld->content_type);
- GRPC_MDSTR_UNREF(channeld->path_key);
- GRPC_MDSTR_UNREF(channeld->authority_key);
- GRPC_MDSTR_UNREF(channeld->host_key);
}
const grpc_channel_filter grpc_http_server_filter = {
diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c
index ff211bc2e6..28496ac2c9 100644
--- a/src/core/client_config/subchannel.c
+++ b/src/core/client_config/subchannel.c
@@ -90,8 +90,6 @@ struct grpc_subchannel {
size_t addr_len;
/** initial string to send to peer */
gpr_slice initial_connect_string;
- /** metadata context */
- grpc_mdctx *mdctx;
/** master channel - the grpc_channel instance that ultimately owns
this channel_data via its channel stack.
We occasionally use this to bump the refcount on the master channel
@@ -271,7 +269,6 @@ static void subchannel_destroy(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
grpc_channel_args_destroy(c->args);
gpr_free(c->addr);
gpr_slice_unref(c->initial_connect_string);
- grpc_mdctx_unref(c->mdctx);
grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
grpc_connector_unref(exec_ctx, c->connector);
gpr_free(c);
@@ -312,11 +309,9 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector,
grpc_set_initial_connect_string(&c->addr, &c->addr_len,
&c->initial_connect_string);
c->args = grpc_channel_args_copy(args->args);
- c->mdctx = args->mdctx;
c->master = args->master;
c->pollset_set = grpc_client_channel_get_connecting_pollset_set(parent_elem);
c->random = random_seed();
- grpc_mdctx_ref(c->mdctx);
grpc_closure_init(&c->connected, subchannel_connected, c);
grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
"subchannel");
@@ -631,7 +626,7 @@ static void publish_transport(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
con->refs = 0;
con->subchannel = c;
grpc_channel_stack_init(exec_ctx, filters, num_filters, c->master, c->args,
- c->mdctx, stk);
+ stk);
grpc_connected_channel_bind_transport(stk, c->connecting_result.transport);
gpr_free((void *)c->connecting_result.filters);
memset(&c->connecting_result, 0, sizeof(c->connecting_result));
@@ -878,10 +873,6 @@ static grpc_subchannel_call *create_call(grpc_exec_ctx *exec_ctx,
return call;
}
-grpc_mdctx *grpc_subchannel_get_mdctx(grpc_subchannel *subchannel) {
- return subchannel->mdctx;
-}
-
grpc_channel *grpc_subchannel_get_master(grpc_subchannel *subchannel) {
return subchannel->master;
}
diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h
index 381b7689b8..85ea3739e4 100644
--- a/src/core/client_config/subchannel.h
+++ b/src/core/client_config/subchannel.h
@@ -147,8 +147,6 @@ struct grpc_subchannel_args {
/** Address to connect to */
struct sockaddr *addr;
size_t addr_len;
- /** metadata context to use */
- grpc_mdctx *mdctx;
/** master channel */
grpc_channel *master;
};
@@ -157,9 +155,6 @@ struct grpc_subchannel_args {
grpc_subchannel *grpc_subchannel_create(grpc_connector *connector,
grpc_subchannel_args *args);
-/** Return the metadata context associated with the subchannel */
-grpc_mdctx *grpc_subchannel_get_mdctx(grpc_subchannel *subchannel);
-
/** Return the master channel associated with the subchannel */
grpc_channel *grpc_subchannel_get_master(grpc_subchannel *subchannel);
diff --git a/src/core/compression/algorithm.c b/src/core/compression/algorithm.c
index fd95a3c891..73d91fa8ea 100644
--- a/src/core/compression/algorithm.c
+++ b/src/core/compression/algorithm.c
@@ -37,7 +37,9 @@
#include <grpc/compression.h>
#include <grpc/support/useful.h>
+#include "src/core/compression/algorithm_metadata.h"
#include "src/core/surface/api_trace.h"
+#include "src/core/transport/static_metadata.h"
int grpc_compression_algorithm_parse(const char *name, size_t name_length,
grpc_compression_algorithm *algorithm) {
@@ -72,17 +74,55 @@ int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
switch (algorithm) {
case GRPC_COMPRESS_NONE:
*name = "identity";
- break;
+ return 1;
case GRPC_COMPRESS_DEFLATE:
*name = "deflate";
- break;
+ return 1;
case GRPC_COMPRESS_GZIP:
*name = "gzip";
- break;
- default:
+ return 1;
+ case GRPC_COMPRESS_ALGORITHMS_COUNT:
return 0;
}
- return 1;
+ 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;
+ return GRPC_COMPRESS_ALGORITHMS_COUNT;
+}
+
+grpc_mdstr *grpc_compression_algorithm_mdstr(
+ grpc_compression_algorithm algorithm) {
+ switch (algorithm) {
+ case GRPC_COMPRESS_NONE:
+ return GRPC_MDSTR_IDENTITY;
+ case GRPC_COMPRESS_DEFLATE:
+ return GRPC_MDSTR_DEFLATE;
+ case GRPC_COMPRESS_GZIP:
+ return GRPC_MDSTR_GZIP;
+ case GRPC_COMPRESS_ALGORITHMS_COUNT:
+ return NULL;
+ }
+ return NULL;
+}
+
+grpc_mdelem *grpc_compression_encoding_mdelem(
+ grpc_compression_algorithm algorithm) {
+ switch (algorithm) {
+ case GRPC_COMPRESS_NONE:
+ return GRPC_MDELEM_GRPC_ENCODING_IDENTITY;
+ case GRPC_COMPRESS_DEFLATE:
+ return GRPC_MDELEM_GRPC_ENCODING_DEFLATE;
+ case GRPC_COMPRESS_GZIP:
+ return GRPC_MDELEM_GRPC_ENCODING_GZIP;
+ case GRPC_COMPRESS_ALGORITHMS_COUNT:
+ return NULL;
+ }
+ return NULL;
}
/* TODO(dgq): Add the ability to specify parameters to the individual
diff --git a/src/core/compression/algorithm_metadata.h b/src/core/compression/algorithm_metadata.h
new file mode 100644
index 0000000000..882633c307
--- /dev/null
+++ b/src/core/compression/algorithm_metadata.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_METADATA_H
+#define GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_METADATA_H
+
+#include <grpc/compression.h>
+#include "src/core/transport/metadata.h"
+
+/** Return compression algorithm based metadata value */
+grpc_mdstr *grpc_compression_algorithm_mdstr(
+ grpc_compression_algorithm algorithm);
+
+/** Return compression algorithm based metadata element (grpc-encoding: xxx) */
+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);
+
+#endif /* GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_METADATA_H */
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 7ff80e6cf8..2be0ea235f 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -207,14 +207,21 @@ static int has_watchers(grpc_fd *fd) {
}
void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done,
- const char *reason) {
+ int *release_fd, const char *reason) {
fd->on_done_closure = on_done;
- shutdown(fd->fd, SHUT_RDWR);
+ fd->released = release_fd != NULL;
+ if (!fd->released) {
+ shutdown(fd->fd, SHUT_RDWR);
+ } else {
+ *release_fd = fd->fd;
+ }
gpr_mu_lock(&fd->mu);
REF_BY(fd, 1, reason); /* remove active status, but keep referenced */
if (!has_watchers(fd)) {
fd->closed = 1;
- close(fd->fd);
+ if (!fd->released) {
+ close(fd->fd);
+ }
grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, 1);
} else {
wake_all_watchers_locked(fd);
@@ -406,7 +413,9 @@ void grpc_fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
}
if (grpc_fd_is_orphaned(fd) && !has_watchers(fd) && !fd->closed) {
fd->closed = 1;
- close(fd->fd);
+ if (!fd->released) {
+ close(fd->fd);
+ }
grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, 1);
}
gpr_mu_unlock(&fd->mu);
diff --git a/src/core/iomgr/fd_posix.h b/src/core/iomgr/fd_posix.h
index dc917ebbc0..d628ef3aaf 100644
--- a/src/core/iomgr/fd_posix.h
+++ b/src/core/iomgr/fd_posix.h
@@ -62,6 +62,7 @@ struct grpc_fd {
gpr_mu mu;
int shutdown;
int closed;
+ int released;
/* The watcher list.
@@ -107,11 +108,12 @@ grpc_fd *grpc_fd_create(int fd, const char *name);
/* Releases fd to be asynchronously destroyed.
on_done is called when the underlying file descriptor is definitely close()d.
If on_done is NULL, no callback will be made.
+ If release_fd is not NULL, it's set to fd and fd will not be closed.
Requires: *fd initialized; no outstanding notify_on_read or
notify_on_write.
MUST NOT be called with a pollset lock taken */
void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done,
- const char *reason);
+ int *release_fd, const char *reason);
/* Begin polling on an fd.
Registers that the given pollset is interested in this fd - so that if read
diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index abd6315ca1..d9d24ee9a3 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -196,7 +196,7 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, int success) {
finish:
if (fd != NULL) {
grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd);
- grpc_fd_orphan(exec_ctx, fd, NULL, "tcp_client_orphan");
+ grpc_fd_orphan(exec_ctx, fd, NULL, NULL, "tcp_client_orphan");
fd = NULL;
}
done = (--ac->refs == 0);
@@ -265,7 +265,7 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
gpr_log(GPR_ERROR, "connect error to '%s': %s", addr_str, strerror(errno));
- grpc_fd_orphan(exec_ctx, fdobj, NULL, "tcp_client_connect_error");
+ grpc_fd_orphan(exec_ctx, fdobj, NULL, NULL, "tcp_client_connect_error");
grpc_exec_ctx_enqueue(exec_ctx, closure, 0);
goto done;
}
diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c
index 915553d509..f3be41aa57 100644
--- a/src/core/iomgr/tcp_posix.c
+++ b/src/core/iomgr/tcp_posix.c
@@ -90,6 +90,8 @@ typedef struct {
grpc_closure *read_cb;
grpc_closure *write_cb;
+ grpc_closure *release_fd_cb;
+ int *release_fd;
grpc_closure read_closure;
grpc_closure write_closure;
@@ -108,7 +110,8 @@ 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, NULL, "tcp_unref_orphan");
+ grpc_fd_orphan(exec_ctx, tcp->em_fd, tcp->release_fd_cb, tcp->release_fd,
+ "tcp_unref_orphan");
gpr_slice_buffer_destroy(&tcp->last_read_buffer);
gpr_free(tcp->peer_string);
gpr_free(tcp);
@@ -452,6 +455,8 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size,
tcp->fd = em_fd->fd;
tcp->read_cb = NULL;
tcp->write_cb = NULL;
+ tcp->release_fd_cb = NULL;
+ tcp->release_fd = NULL;
tcp->incoming_buffer = NULL;
tcp->slice_size = slice_size;
tcp->iov_size = 1;
@@ -468,4 +473,13 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size,
return &tcp->base;
}
+void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
+ int *fd, grpc_closure *done) {
+ grpc_tcp *tcp = (grpc_tcp *)ep;
+ GPR_ASSERT(ep->vtable == &vtable);
+ tcp->release_fd = fd;
+ tcp->release_fd_cb = done;
+ TCP_UNREF(exec_ctx, tcp, "destroy");
+}
+
#endif
diff --git a/src/core/iomgr/tcp_posix.h b/src/core/iomgr/tcp_posix.h
index 40b3ae2679..b554983ae1 100644
--- a/src/core/iomgr/tcp_posix.h
+++ b/src/core/iomgr/tcp_posix.h
@@ -56,4 +56,10 @@ extern int grpc_tcp_trace;
grpc_endpoint *grpc_tcp_create(grpc_fd *fd, size_t read_slice_size,
const char *peer_string);
+/* Destroy the tcp endpoint without closing its fd. *fd will be set and done
+ * will be called when the endpoint is destroyed.
+ * Requires: ep must be a tcp endpoint and fd must not be NULL. */
+void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
+ int *fd, grpc_closure *done);
+
#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_POSIX_H */
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 0ece77c4e8..a89ee02d34 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -193,7 +193,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
}
sp->destroyed_closure.cb = destroyed_port;
sp->destroyed_closure.cb_arg = s;
- grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure,
+ grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
"tcp_listener_shutdown");
}
gpr_mu_unlock(&s->mu);
diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c
index 9903e970e6..782fbd9f46 100644
--- a/src/core/iomgr/udp_server.c
+++ b/src/core/iomgr/udp_server.c
@@ -179,7 +179,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
}
sp->destroyed_closure.cb = destroyed_port;
sp->destroyed_closure.cb_arg = s;
- grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure,
+ grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
"udp_listener_shutdown");
}
gpr_mu_unlock(&s->mu);
diff --git a/src/core/iomgr/workqueue_posix.c b/src/core/iomgr/workqueue_posix.c
index c087b887b8..2e30178131 100644
--- a/src/core/iomgr/workqueue_posix.c
+++ b/src/core/iomgr/workqueue_posix.c
@@ -115,7 +115,7 @@ static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, int success) {
/* HACK: let wakeup_fd code know that we stole the fd */
workqueue->wakeup_fd.read_fd = 0;
grpc_wakeup_fd_destroy(&workqueue->wakeup_fd);
- grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, "destroy");
+ grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, NULL, "destroy");
gpr_free(workqueue);
} else {
gpr_mu_lock(&workqueue->mu);
diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c
index d3d948ae5f..4e5be03d85 100644
--- a/src/core/security/client_auth_filter.c
+++ b/src/core/security/client_auth_filter.c
@@ -45,6 +45,7 @@
#include "src/core/security/security_connector.h"
#include "src/core/security/credentials.h"
#include "src/core/surface/call.h"
+#include "src/core/transport/static_metadata.h"
#define MAX_CREDENTIALS_METADATA_COUNT 4
@@ -67,11 +68,6 @@ typedef struct {
/* We can have a per-channel credentials. */
typedef struct {
grpc_channel_security_connector *security_connector;
- grpc_mdctx *md_ctx;
- grpc_mdstr *authority_string;
- grpc_mdstr *path_string;
- grpc_mdstr *error_msg_key;
- grpc_mdstr *status_key;
} channel_data;
static void reset_auth_metadata_context(
@@ -104,7 +100,6 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_credentials_status status) {
grpc_call_element *elem = (grpc_call_element *)user_data;
call_data *calld = elem->call_data;
- channel_data *chand = elem->channel_data;
grpc_transport_stream_op *op = &calld->op;
grpc_metadata_batch *mdb;
size_t i;
@@ -120,7 +115,7 @@ 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(chand->md_ctx, gpr_slice_ref(md_elems[i].key),
+ grpc_mdelem_from_slices(gpr_slice_ref(md_elems[i].key),
gpr_slice_ref(md_elems[i].value)));
}
grpc_call_next_op(exec_ctx, elem, op);
@@ -243,10 +238,10 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
grpc_mdelem *md = l->md;
/* Pointer comparison is OK for md_elems created from the same context.
*/
- if (md->key == chand->authority_string) {
+ 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 == chand->path_string) {
+ } else if (md->key == GRPC_MDSTR_PATH) {
if (calld->method != NULL) GRPC_MDSTR_UNREF(calld->method);
calld->method = GRPC_MDSTR_REF(md->value);
}
@@ -326,11 +321,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
chand->security_connector =
(grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(
sc, "client_auth_filter");
- chand->md_ctx = args->metadata_context;
- chand->authority_string = grpc_mdstr_from_string(chand->md_ctx, ":authority");
- chand->path_string = grpc_mdstr_from_string(chand->md_ctx, ":path");
- chand->error_msg_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-message");
- chand->status_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-status");
}
/* Destructor for channel data */
@@ -339,19 +329,8 @@ 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_channel_security_connector *ctx = chand->security_connector;
- if (ctx != NULL)
+ if (ctx != NULL) {
GRPC_SECURITY_CONNECTOR_UNREF(&ctx->base, "client_auth_filter");
- if (chand->authority_string != NULL) {
- GRPC_MDSTR_UNREF(chand->authority_string);
- }
- if (chand->error_msg_key != NULL) {
- GRPC_MDSTR_UNREF(chand->error_msg_key);
- }
- if (chand->status_key != NULL) {
- GRPC_MDSTR_UNREF(chand->status_key);
- }
- if (chand->path_string != NULL) {
- GRPC_MDSTR_UNREF(chand->path_string);
}
}
diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c
index fee962b576..5cfee6d139 100644
--- a/src/core/security/server_auth_filter.c
+++ b/src/core/security/server_auth_filter.c
@@ -58,7 +58,6 @@ typedef struct call_data {
typedef struct channel_data {
grpc_auth_context *auth_context;
grpc_server_credentials *creds;
- grpc_mdctx *mdctx;
} channel_data;
static grpc_metadata_array metadata_batch_to_md_array(
@@ -247,7 +246,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
chand->auth_context =
GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter");
chand->creds = grpc_server_credentials_ref(creds);
- chand->mdctx = args->metadata_context;
}
/* Destructor for channel data */
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 1ea269bf8f..14a5d0fef6 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -87,7 +87,7 @@ static void state_unref(grpc_server_secure_state *state) {
}
static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep,
- grpc_transport *transport, grpc_mdctx *mdctx) {
+ grpc_transport *transport) {
static grpc_channel_filter const *extra_filters[] = {
&grpc_server_auth_filter, &grpc_http_server_filter};
grpc_server_secure_state *state = statep;
@@ -99,7 +99,7 @@ static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep,
grpc_server_get_channel_args(state->server), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
grpc_server_setup_transport(exec_ctx, state->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx, args_copy);
+ GPR_ARRAY_SIZE(extra_filters), args_copy);
grpc_channel_args_destroy(args_copy);
}
@@ -130,16 +130,14 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
grpc_endpoint *secure_endpoint) {
grpc_server_secure_state *state = statep;
grpc_transport *transport;
- grpc_mdctx *mdctx;
if (status == GRPC_SECURITY_OK) {
gpr_mu_lock(&state->mu);
remove_tcp_from_list_locked(state, wrapped_endpoint);
if (!state->is_shutdown) {
- mdctx = grpc_mdctx_create();
transport = grpc_create_chttp2_transport(
exec_ctx, grpc_server_get_channel_args(state->server),
- secure_endpoint, mdctx, 0);
- setup_transport(exec_ctx, state, transport, mdctx);
+ secure_endpoint, 0);
+ setup_transport(exec_ctx, state, transport);
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
} else {
/* We need to consume this here, because the server may already have gone
diff --git a/src/core/support/slice.c b/src/core/support/slice.c
index 53024e88f1..5b091f17b0 100644
--- a/src/core/support/slice.c
+++ b/src/core/support/slice.c
@@ -57,6 +57,21 @@ void gpr_slice_unref(gpr_slice slice) {
}
}
+/* gpr_slice_from_static_string support structure - a refcount that does
+ nothing */
+static void noop_ref_or_unref(void *unused) {}
+
+static gpr_slice_refcount noop_refcount = {noop_ref_or_unref,
+ noop_ref_or_unref};
+
+gpr_slice gpr_slice_from_static_string(const char *s) {
+ gpr_slice slice;
+ slice.refcount = &noop_refcount;
+ slice.data.refcounted.bytes = (gpr_uint8 *)s;
+ slice.data.refcounted.length = strlen(s);
+ return slice;
+}
+
/* gpr_slice_new support structures - we create a refcount object extended
with the user provided data pointer & destroy function */
typedef struct new_slice_refcount {
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 86d5fca388..49a0c7e04e 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -43,6 +43,7 @@
#include <grpc/support/useful.h>
#include "src/core/channel/channel_stack.h"
+#include "src/core/compression/algorithm_metadata.h"
#include "src/core/iomgr/timer.h"
#include "src/core/profiling/timers.h"
#include "src/core/support/string.h"
@@ -50,6 +51,7 @@
#include "src/core/surface/call.h"
#include "src/core/surface/channel.h"
#include "src/core/surface/completion_queue.h"
+#include "src/core/transport/static_metadata.h"
/** The maximum number of concurrent batches possible.
Based upon the maximum number of individually queueable ops in the batch
@@ -135,7 +137,6 @@ struct grpc_call {
grpc_channel *channel;
grpc_call *parent;
grpc_call *first_child;
- grpc_mdctx *metadata_context;
/* TODO(ctiller): share with cq if possible? */
gpr_mu mu;
@@ -267,7 +268,6 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
}
call->send_deadline = send_deadline;
GRPC_CHANNEL_INTERNAL_REF(channel, "call");
- call->metadata_context = grpc_channel_get_metadata_context(channel);
/* initial refcount dropped by grpc_call_destroy */
grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call,
call->context, server_transport_data,
@@ -567,9 +567,8 @@ static int prepare_application_metadata(grpc_call *call, int count,
grpc_metadata *md = &metadata[i];
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(call->metadata_context, md->key,
- (const gpr_uint8 *)md->value,
- md->value_length);
+ l->md = grpc_mdelem_from_string_and_buffer(
+ md->key, (const gpr_uint8 *)md->value, md->value_length);
if (!grpc_mdstr_is_legal_header(l->md->key)) {
gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s",
grpc_mdstr_as_c_string(l->md->key));
@@ -712,8 +711,7 @@ static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
grpc_status_code status,
const char *description) {
grpc_mdstr *details =
- description ? grpc_mdstr_from_string(c->metadata_context, description)
- : NULL;
+ description ? grpc_mdstr_from_string(description) : NULL;
cancel_closure *cc = gpr_malloc(sizeof(*cc));
GPR_ASSERT(status != GRPC_STATUS_OK);
@@ -788,8 +786,12 @@ static void destroy_status(void *ignored) {}
static gpr_uint32 decode_status(grpc_mdelem *md) {
gpr_uint32 status;
- void *user_data = grpc_mdelem_get_user_data(md, destroy_status);
- if (user_data) {
+ 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;
+ user_data = grpc_mdelem_get_user_data(md, destroy_status);
+ if (user_data != NULL) {
status = ((gpr_uint32)(gpr_intptr)user_data) - STATUS_OFFSET;
} else {
if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value),
@@ -803,38 +805,23 @@ static gpr_uint32 decode_status(grpc_mdelem *md) {
return status;
}
-/* just as for status above, we need to offset: metadata userdata can't hold a
- * zero (null), which in this case is used to signal no compression */
-#define COMPRESS_OFFSET 1
-static void destroy_compression(void *ignored) {}
-
static gpr_uint32 decode_compression(grpc_mdelem *md) {
- grpc_compression_algorithm algorithm;
- void *user_data = grpc_mdelem_get_user_data(md, destroy_compression);
- if (user_data) {
- algorithm =
- ((grpc_compression_algorithm)(gpr_intptr)user_data) - COMPRESS_OFFSET;
- } else {
+ grpc_compression_algorithm algorithm =
+ grpc_compression_algorithm_from_mdstr(md->value);
+ if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) {
const char *md_c_str = grpc_mdstr_as_c_string(md->value);
- if (!grpc_compression_algorithm_parse(md_c_str, strlen(md_c_str),
- &algorithm)) {
- gpr_log(GPR_ERROR, "Invalid compression algorithm: '%s'", md_c_str);
- assert(0);
- }
- grpc_mdelem_set_user_data(
- md, destroy_compression,
- (void *)(gpr_intptr)(algorithm + COMPRESS_OFFSET));
+ gpr_log(GPR_ERROR, "Invalid compression algorithm: '%s'", md_c_str);
}
return algorithm;
}
static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) {
- if (elem->key == grpc_channel_get_status_string(call->channel)) {
+ if (elem->key == GRPC_MDSTR_GRPC_STATUS) {
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_channel_get_message_string(call->channel)) {
+ } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) {
GPR_TIMER_BEGIN("status-details", 0);
set_status_details(call, STATUS_FROM_WIRE, GRPC_MDSTR_REF(elem->value));
GPR_TIMER_END("status-details", 0);
@@ -867,14 +854,12 @@ static grpc_mdelem *recv_initial_filter(void *callp, grpc_mdelem *elem) {
elem = recv_common_filter(call, elem);
if (elem == NULL) {
return NULL;
- } else if (elem->key ==
- grpc_channel_get_compression_algorithm_string(call->channel)) {
+ } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
GPR_TIMER_BEGIN("compression_algorithm", 0);
set_compression_algorithm(call, decode_compression(elem));
GPR_TIMER_END("compression_algorithm", 0);
return NULL;
- } else if (elem->key == grpc_channel_get_encodings_accepted_by_peer_string(
- call->channel)) {
+ } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
set_encodings_accepted_by_peer(call, elem);
GPR_TIMER_END("encodings_accepted_by_peer", 0);
@@ -1241,10 +1226,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *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(
- call->metadata_context,
- GRPC_MDSTR_REF(grpc_channel_get_message_string(call->channel)),
+ GRPC_MDSTR_GRPC_MESSAGE,
grpc_mdstr_from_string(
- call->metadata_context,
op->data.send_status_from_server.status_details));
call->send_extra_metadata_count++;
set_status_details(
diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
index a9a5f828f2..859197412b 100644
--- a/src/core/surface/channel.c
+++ b/src/core/surface/channel.c
@@ -46,6 +46,7 @@
#include "src/core/surface/api_trace.h"
#include "src/core/surface/call.h"
#include "src/core/surface/init.h"
+#include "src/core/transport/static_metadata.h"
/** Cache grpc-status: X mdelems for X = 0..NUM_CACHED_STATUS_ELEMS.
* Avoids needing to take a metadata context lock for sending status
@@ -64,17 +65,7 @@ struct grpc_channel {
int is_client;
gpr_refcount refs;
gpr_uint32 max_message_length;
- grpc_mdctx *metadata_context;
- /** mdstr for the grpc-status key */
- grpc_mdstr *grpc_status_string;
- grpc_mdstr *grpc_compression_algorithm_string;
- grpc_mdstr *grpc_encodings_accepted_by_peer_string;
- grpc_mdstr *grpc_message_string;
- grpc_mdstr *path_string;
- grpc_mdstr *authority_string;
grpc_mdelem *default_authority;
- /** mdelem for grpc-status: 0 thru grpc-status: 2 */
- grpc_mdelem *grpc_status_elem[NUM_CACHED_STATUS_ELEMS];
gpr_mu registered_call_mu;
registered_call *registered_calls;
@@ -93,7 +84,7 @@ struct grpc_channel {
grpc_channel *grpc_channel_create_from_filters(
grpc_exec_ctx *exec_ctx, const char *target,
const grpc_channel_filter **filters, size_t num_filters,
- const grpc_channel_args *args, grpc_mdctx *mdctx, int is_client) {
+ const grpc_channel_args *args, int is_client) {
size_t i;
size_t size =
sizeof(grpc_channel) + grpc_channel_stack_size(filters, num_filters);
@@ -104,22 +95,6 @@ grpc_channel *grpc_channel_create_from_filters(
channel->is_client = is_client;
/* decremented by grpc_channel_destroy */
gpr_ref_init(&channel->refs, 1);
- channel->metadata_context = mdctx;
- channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status");
- channel->grpc_compression_algorithm_string =
- grpc_mdstr_from_string(mdctx, "grpc-encoding");
- channel->grpc_encodings_accepted_by_peer_string =
- grpc_mdstr_from_string(mdctx, "grpc-accept-encoding");
- channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message");
- for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) {
- char buf[GPR_LTOA_MIN_BUFSIZE];
- gpr_ltoa((long)i, buf);
- channel->grpc_status_elem[i] = grpc_mdelem_from_metadata_strings(
- mdctx, GRPC_MDSTR_REF(channel->grpc_status_string),
- grpc_mdstr_from_string(mdctx, buf));
- }
- channel->path_string = grpc_mdstr_from_string(mdctx, ":path");
- channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority");
gpr_mu_init(&channel->registered_call_mu);
channel->registered_calls = NULL;
@@ -146,7 +121,7 @@ grpc_channel *grpc_channel_create_from_filters(
GRPC_MDELEM_UNREF(channel->default_authority);
}
channel->default_authority = grpc_mdelem_from_strings(
- mdctx, ":authority", args->args[i].value.string);
+ ":authority", args->args[i].value.string);
}
} else if (0 ==
strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
@@ -160,7 +135,7 @@ grpc_channel *grpc_channel_create_from_filters(
GRPC_ARG_DEFAULT_AUTHORITY);
} else {
channel->default_authority = grpc_mdelem_from_strings(
- mdctx, ":authority", args->args[i].value.string);
+ ":authority", args->args[i].value.string);
}
}
}
@@ -171,14 +146,13 @@ grpc_channel *grpc_channel_create_from_filters(
target != NULL) {
char *default_authority = grpc_get_default_authority(target);
if (default_authority) {
- channel->default_authority = grpc_mdelem_from_strings(
- channel->metadata_context, ":authority", default_authority);
+ channel->default_authority =
+ grpc_mdelem_from_strings(":authority", default_authority);
}
gpr_free(default_authority);
}
grpc_channel_stack_init(exec_ctx, filters, num_filters, channel, args,
- channel->metadata_context,
CHANNEL_STACK_FROM_CHANNEL(channel));
return channel;
@@ -227,13 +201,10 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
channel, parent_call, propagation_mask, cq,
- grpc_mdelem_from_metadata_strings(
- channel->metadata_context, GRPC_MDSTR_REF(channel->path_string),
- grpc_mdstr_from_string(channel->metadata_context, method)),
- host ? grpc_mdelem_from_metadata_strings(
- channel->metadata_context,
- GRPC_MDSTR_REF(channel->authority_string),
- grpc_mdstr_from_string(channel->metadata_context, host))
+ grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+ grpc_mdstr_from_string(method)),
+ host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
+ grpc_mdstr_from_string(host))
: NULL,
deadline);
}
@@ -245,15 +216,11 @@ 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(
- channel->metadata_context, GRPC_MDSTR_REF(channel->path_string),
- grpc_mdstr_from_string(channel->metadata_context, method));
- rc->authority =
- host ? grpc_mdelem_from_metadata_strings(
- channel->metadata_context,
- GRPC_MDSTR_REF(channel->authority_string),
- grpc_mdstr_from_string(channel->metadata_context, host))
- : NULL;
+ 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;
gpr_mu_lock(&channel->registered_call_mu);
rc->next = channel->registered_calls;
channel->registered_calls = rc;
@@ -293,17 +260,7 @@ void grpc_channel_internal_ref(grpc_channel *c) {
}
static void destroy_channel(grpc_exec_ctx *exec_ctx, grpc_channel *channel) {
- size_t i;
grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(channel));
- for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) {
- GRPC_MDELEM_UNREF(channel->grpc_status_elem[i]);
- }
- GRPC_MDSTR_UNREF(channel->grpc_status_string);
- GRPC_MDSTR_UNREF(channel->grpc_compression_algorithm_string);
- GRPC_MDSTR_UNREF(channel->grpc_encodings_accepted_by_peer_string);
- GRPC_MDSTR_UNREF(channel->grpc_message_string);
- GRPC_MDSTR_UNREF(channel->path_string);
- GRPC_MDSTR_UNREF(channel->authority_string);
while (channel->registered_calls) {
registered_call *rc = channel->registered_calls;
channel->registered_calls = rc->next;
@@ -316,7 +273,6 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, grpc_channel *channel) {
if (channel->default_authority != NULL) {
GRPC_MDELEM_UNREF(channel->default_authority);
}
- grpc_mdctx_unref(channel->metadata_context);
gpr_mu_destroy(&channel->registered_call_mu);
gpr_free(channel->target);
gpr_free(channel);
@@ -355,38 +311,19 @@ grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel) {
return CHANNEL_STACK_FROM_CHANNEL(channel);
}
-grpc_mdctx *grpc_channel_get_metadata_context(grpc_channel *channel) {
- return channel->metadata_context;
-}
-
-grpc_mdstr *grpc_channel_get_status_string(grpc_channel *channel) {
- return channel->grpc_status_string;
-}
-
-grpc_mdstr *grpc_channel_get_compression_algorithm_string(
- grpc_channel *channel) {
- return channel->grpc_compression_algorithm_string;
-}
-
-grpc_mdstr *grpc_channel_get_encodings_accepted_by_peer_string(
- grpc_channel *channel) {
- return channel->grpc_encodings_accepted_by_peer_string;
-}
-
grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
- if (i >= 0 && i < NUM_CACHED_STATUS_ELEMS) {
- return GRPC_MDELEM_REF(channel->grpc_status_elem[i]);
- } else {
- char tmp[GPR_LTOA_MIN_BUFSIZE];
- gpr_ltoa(i, tmp);
- return grpc_mdelem_from_metadata_strings(
- channel->metadata_context, GRPC_MDSTR_REF(channel->grpc_status_string),
- grpc_mdstr_from_string(channel->metadata_context, tmp));
+ char tmp[GPR_LTOA_MIN_BUFSIZE];
+ switch (i) {
+ case 0:
+ return GRPC_MDELEM_GRPC_STATUS_0;
+ case 1:
+ return GRPC_MDELEM_GRPC_STATUS_1;
+ case 2:
+ return GRPC_MDELEM_GRPC_STATUS_2;
}
-}
-
-grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel) {
- return channel->grpc_message_string;
+ gpr_ltoa(i, tmp);
+ return grpc_mdelem_from_metadata_strings(GRPC_MDSTR_GRPC_STATUS,
+ grpc_mdstr_from_string(tmp));
}
gpr_uint32 grpc_channel_get_max_message_length(grpc_channel *channel) {
diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h
index e5030d52d2..7dea609ebc 100644
--- a/src/core/surface/channel.h
+++ b/src/core/surface/channel.h
@@ -40,26 +40,17 @@
grpc_channel *grpc_channel_create_from_filters(
grpc_exec_ctx *exec_ctx, const char *target,
const grpc_channel_filter **filters, size_t count,
- const grpc_channel_args *args, grpc_mdctx *mdctx, int is_client);
+ const grpc_channel_args *args, int is_client);
/** Get a (borrowed) pointer to this channels underlying channel stack */
grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
-/** Get a (borrowed) pointer to the channel wide metadata context */
-grpc_mdctx *grpc_channel_get_metadata_context(grpc_channel *channel);
-
/** Get a grpc_mdelem of grpc-status: X where X is the numeric value of
status_code.
The returned elem is owned by the caller. */
grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel,
int status_code);
-grpc_mdstr *grpc_channel_get_status_string(grpc_channel *channel);
-grpc_mdstr *grpc_channel_get_compression_algorithm_string(
- grpc_channel *channel);
-grpc_mdstr *grpc_channel_get_encodings_accepted_by_peer_string(
- grpc_channel *channel);
-grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel);
gpr_uint32 grpc_channel_get_max_message_length(grpc_channel *channel);
#ifdef GRPC_CHANNEL_REF_COUNT_DEBUG
diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c
index 921f8c275e..6d40780497 100644
--- a/src/core/surface/channel_create.c
+++ b/src/core/surface/channel_create.c
@@ -63,8 +63,6 @@ typedef struct {
grpc_endpoint *tcp;
- grpc_mdctx *mdctx;
-
grpc_closure connected;
} connector;
@@ -76,7 +74,6 @@ static void connector_ref(grpc_connector *con) {
static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
connector *c = (connector *)con;
if (gpr_unref(&c->refs)) {
- grpc_mdctx_unref(c->mdctx);
/* c->initial_string_buffer does not need to be destroyed */
gpr_free(c);
}
@@ -103,7 +100,7 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, int success) {
&c->initial_string_sent);
}
c->result->transport = grpc_create_chttp2_transport(
- exec_ctx, c->args.channel_args, tcp, c->mdctx, 1);
+ exec_ctx, c->args.channel_args, tcp, 1);
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
0);
GPR_ASSERT(c->result->transport);
@@ -143,7 +140,6 @@ static const grpc_connector_vtable connector_vtable = {
typedef struct {
grpc_subchannel_factory base;
gpr_refcount refs;
- grpc_mdctx *mdctx;
grpc_channel_args *merge_args;
grpc_channel *master;
} subchannel_factory;
@@ -159,7 +155,6 @@ static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
if (gpr_unref(&f->refs)) {
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
grpc_channel_args_destroy(f->merge_args);
- grpc_mdctx_unref(f->mdctx);
gpr_free(f);
}
}
@@ -174,10 +169,7 @@ static grpc_subchannel *subchannel_factory_create_subchannel(
grpc_subchannel *s;
memset(c, 0, sizeof(*c));
c->base.vtable = &connector_vtable;
- c->mdctx = f->mdctx;
- grpc_mdctx_ref(c->mdctx);
gpr_ref_init(&c->refs, 1);
- args->mdctx = f->mdctx;
args->args = final_args;
args->master = f->master;
s = grpc_subchannel_create(&c->base, args);
@@ -202,7 +194,6 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
const grpc_channel_filter *filters[MAX_FILTERS];
grpc_resolver *resolver;
subchannel_factory *f;
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
size_t n = 0;
GRPC_API_TRACE(
@@ -216,14 +207,12 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
filters[n++] = &grpc_client_channel_filter;
GPR_ASSERT(n <= MAX_FILTERS);
- channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
- args, mdctx, 1);
+ channel =
+ grpc_channel_create_from_filters(&exec_ctx, target, filters, n, args, 1);
f = gpr_malloc(sizeof(*f));
f->base.vtable = &subchannel_factory_vtable;
gpr_ref_init(&f->refs, 1);
- grpc_mdctx_ref(mdctx);
- f->mdctx = mdctx;
f->merge_args = grpc_channel_args_copy(args);
f->master = channel;
GRPC_CHANNEL_INTERNAL_REF(f->master, "subchannel_factory");
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
index f8cba01cad..04d68620f1 100644
--- a/src/core/surface/init.c
+++ b/src/core/surface/init.c
@@ -93,6 +93,7 @@ void grpc_init(void) {
gpr_mu_lock(&g_init_mu);
if (++g_initializations == 1) {
gpr_time_init();
+ grpc_mdctx_global_init();
grpc_lb_policy_registry_init(grpc_pick_first_lb_factory_create());
grpc_register_lb_policy(grpc_pick_first_lb_factory_create());
grpc_register_lb_policy(grpc_round_robin_lb_factory_create());
@@ -147,6 +148,7 @@ void grpc_shutdown(void) {
g_all_of_the_plugins[i].destroy();
}
}
+ grpc_mdctx_global_shutdown();
}
gpr_mu_unlock(&g_init_mu);
}
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
index fc458a603d..0247116ebb 100644
--- a/src/core/surface/lame_client.c
+++ b/src/core/surface/lame_client.c
@@ -49,7 +49,6 @@ typedef struct {
} call_data;
typedef struct {
- grpc_mdctx *mdctx;
grpc_channel *master;
grpc_status_code error_code;
const char *error_message;
@@ -60,9 +59,9 @@ static void fill_metadata(grpc_call_element *elem, grpc_metadata_batch *mdb) {
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(chand->mdctx, "grpc-status", tmp);
- calld->details.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-message",
- chand->error_message);
+ calld->status.md = grpc_mdelem_from_strings("grpc-status", tmp);
+ calld->details.md =
+ grpc_mdelem_from_strings("grpc-message", chand->error_message);
calld->status.prev = calld->details.next = NULL;
calld->status.next = &calld->details;
calld->details.prev = &calld->status;
@@ -104,7 +103,8 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx,
}
static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- grpc_call_element_args *args) {}
+ grpc_call_element_args *args) {
+}
static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem) {}
@@ -115,7 +115,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
channel_data *chand = elem->channel_data;
GPR_ASSERT(args->is_first);
GPR_ASSERT(args->is_last);
- chand->mdctx = args->metadata_context;
chand->master = args->master;
}
@@ -139,8 +138,8 @@ grpc_channel *grpc_lame_client_channel_create(const char *target,
channel_data *chand;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
static const grpc_channel_filter *filters[] = {&lame_filter};
- channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, 1,
- NULL, grpc_mdctx_create(), 1);
+ channel =
+ grpc_channel_create_from_filters(&exec_ctx, target, filters, 1, NULL, 1);
elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
GRPC_API_TRACE(
"grpc_lame_client_channel_create(target=%s, error_code=%d, "
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index e8afe1a908..374b44b406 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -71,8 +71,6 @@ typedef struct {
grpc_endpoint *newly_connecting_endpoint;
grpc_closure connected_closure;
-
- grpc_mdctx *mdctx;
} connector;
static void connector_ref(grpc_connector *con) {
@@ -83,7 +81,6 @@ static void connector_ref(grpc_connector *con) {
static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
connector *c = (connector *)con;
if (gpr_unref(&c->refs)) {
- grpc_mdctx_unref(c->mdctx);
/* c->initial_string_buffer does not need to be destroyed */
gpr_free(c);
}
@@ -110,7 +107,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
c->connecting_endpoint = NULL;
gpr_mu_unlock(&c->mu);
c->result->transport = grpc_create_chttp2_transport(
- exec_ctx, c->args.channel_args, secure_endpoint, c->mdctx, 1);
+ exec_ctx, c->args.channel_args, secure_endpoint, 1);
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
0);
c->result->filters = gpr_malloc(sizeof(grpc_channel_filter *) * 2);
@@ -198,7 +195,6 @@ static const grpc_connector_vtable connector_vtable = {
typedef struct {
grpc_subchannel_factory base;
gpr_refcount refs;
- grpc_mdctx *mdctx;
grpc_channel_args *merge_args;
grpc_channel_security_connector *security_connector;
grpc_channel *master;
@@ -217,7 +213,6 @@ static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
"subchannel_factory");
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
grpc_channel_args_destroy(f->merge_args);
- grpc_mdctx_unref(f->mdctx);
gpr_free(f);
}
}
@@ -233,13 +228,10 @@ static grpc_subchannel *subchannel_factory_create_subchannel(
memset(c, 0, sizeof(*c));
c->base.vtable = &connector_vtable;
c->security_connector = f->security_connector;
- c->mdctx = f->mdctx;
gpr_mu_init(&c->mu);
- grpc_mdctx_ref(c->mdctx);
gpr_ref_init(&c->refs, 1);
args->args = final_args;
args->master = f->master;
- args->mdctx = f->mdctx;
s = grpc_subchannel_create(&c->base, args);
grpc_connector_unref(exec_ctx, &c->base);
grpc_channel_args_destroy(final_args);
@@ -263,7 +255,6 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
grpc_channel_args *args_copy;
grpc_channel_args *new_args_from_connector;
grpc_channel_security_connector *security_connector;
- grpc_mdctx *mdctx;
grpc_resolver *resolver;
subchannel_factory *f;
#define MAX_FILTERS 3
@@ -293,7 +284,6 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
target, GRPC_STATUS_INVALID_ARGUMENT,
"Failed to create security connector.");
}
- mdctx = grpc_mdctx_create();
connector_arg = grpc_security_connector_to_arg(&security_connector->base);
args_copy = grpc_channel_args_copy_and_add(
@@ -307,13 +297,11 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
GPR_ASSERT(n <= MAX_FILTERS);
channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
- args_copy, mdctx, 1);
+ args_copy, 1);
f = gpr_malloc(sizeof(*f));
f->base.vtable = &subchannel_factory_vtable;
gpr_ref_init(&f->refs, 1);
- grpc_mdctx_ref(mdctx);
- f->mdctx = mdctx;
GRPC_SECURITY_CONNECTOR_REF(&security_connector->base, "subchannel_factory");
f->security_connector = security_connector;
f->merge_args = grpc_channel_args_copy(args_copy);
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index e9f380083f..cdbd542d9a 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -54,6 +54,7 @@
#include "src/core/surface/completion_queue.h"
#include "src/core/surface/init.h"
#include "src/core/transport/metadata.h"
+#include "src/core/transport/static_metadata.h"
typedef struct listener {
void *arg;
@@ -108,8 +109,6 @@ struct channel_data {
grpc_server *server;
grpc_connectivity_state connectivity_state;
grpc_channel *channel;
- grpc_mdstr *path_key;
- grpc_mdstr *authority_key;
/* linked list of all channels on a server */
channel_data *next;
channel_data *prev;
@@ -558,12 +557,11 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data;
- channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data;
- if (md->key == chand->path_key) {
+ if (md->key == GRPC_MDSTR_PATH) {
calld->path = GRPC_MDSTR_REF(md->value);
return NULL;
- } else if (md->key == chand->authority_key) {
+ } else if (md->key == GRPC_MDSTR_AUTHORITY) {
calld->host = GRPC_MDSTR_REF(md->value);
return NULL;
}
@@ -718,9 +716,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(!args->is_last);
chand->server = NULL;
chand->channel = NULL;
- chand->path_key = grpc_mdstr_from_string(args->metadata_context, ":path");
- chand->authority_key =
- grpc_mdstr_from_string(args->metadata_context, ":authority");
chand->next = chand->prev = chand;
chand->registered_methods = NULL;
chand->connectivity_state = GRPC_CHANNEL_IDLE;
@@ -750,8 +745,6 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
chand->next = chand->prev = chand;
maybe_finish_shutdown(exec_ctx, chand->server);
gpr_mu_unlock(&chand->server->mu_global);
- GRPC_MDSTR_UNREF(chand->path_key);
- GRPC_MDSTR_UNREF(chand->authority_key);
server_unref(exec_ctx, chand->server);
}
}
@@ -894,7 +887,7 @@ void grpc_server_start(grpc_server *server) {
void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
grpc_transport *transport,
grpc_channel_filter const **extra_filters,
- size_t num_extra_filters, grpc_mdctx *mdctx,
+ size_t num_extra_filters,
const grpc_channel_args *args) {
size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
grpc_channel_filter const **filters =
@@ -929,7 +922,7 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
}
channel = grpc_channel_create_from_filters(exec_ctx, NULL, filters,
- num_filters, args, mdctx, 0);
+ num_filters, args, 0);
chand = (channel_data *)grpc_channel_stack_element(
grpc_channel_get_channel_stack(channel), 0)->channel_data;
chand->server = s;
@@ -948,8 +941,8 @@ 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(mdctx, rm->host) : NULL;
- method = grpc_mdstr_from_string(mdctx, rm->method);
+ 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);
for (probes = 0; chand->registered_methods[(hash + probes) % slots]
.server_registered_method != NULL;
diff --git a/src/core/surface/server.h b/src/core/surface/server.h
index 4c46d07679..a957fdb360 100644
--- a/src/core/surface/server.h
+++ b/src/core/surface/server.h
@@ -57,7 +57,7 @@ void grpc_server_add_listener(
void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *server,
grpc_transport *transport,
grpc_channel_filter const **extra_filters,
- size_t num_extra_filters, grpc_mdctx *mdctx,
+ size_t num_extra_filters,
const grpc_channel_args *args);
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
index 1408f9c159..990bc4aa23 100644
--- a/src/core/surface/server_chttp2.c
+++ b/src/core/surface/server_chttp2.c
@@ -44,11 +44,11 @@
#include <grpc/support/useful.h>
static void setup_transport(grpc_exec_ctx *exec_ctx, void *server,
- grpc_transport *transport, grpc_mdctx *mdctx) {
+ grpc_transport *transport) {
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
grpc_server_setup_transport(exec_ctx, server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
+ GPR_ARRAY_SIZE(extra_filters),
grpc_server_get_channel_args(server));
}
@@ -61,10 +61,9 @@ static void new_transport(grpc_exec_ctx *exec_ctx, void *server,
* (as in server_secure_chttp2.c) needs to add synchronization to avoid this
* case.
*/
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_transport *transport = grpc_create_chttp2_transport(
- exec_ctx, grpc_server_get_channel_args(server), tcp, mdctx, 0);
- setup_transport(exec_ctx, server, transport, mdctx);
+ exec_ctx, grpc_server_get_channel_args(server), tcp, 0);
+ setup_transport(exec_ctx, server, transport);
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
}
diff --git a/src/core/transport/chttp2/hpack_encoder.c b/src/core/transport/chttp2/hpack_encoder.c
index 62b60abaf5..28d5433d15 100644
--- a/src/core/transport/chttp2/hpack_encoder.c
+++ b/src/core/transport/chttp2/hpack_encoder.c
@@ -44,6 +44,7 @@
#include "src/core/transport/chttp2/hpack_table.h"
#include "src/core/transport/chttp2/timeout_encoding.h"
#include "src/core/transport/chttp2/varint.h"
+#include "src/core/transport/static_metadata.h"
#define HASH_FRAGMENT_1(x) ((x)&255)
#define HASH_FRAGMENT_2(x) ((x >> 8) & 255)
@@ -452,8 +453,7 @@ static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
grpc_chttp2_encode_timeout(
gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str);
mdelem = grpc_mdelem_from_metadata_strings(
- c->mdctx, GRPC_MDSTR_REF(c->timeout_key_str),
- grpc_mdstr_from_string(c->mdctx, timeout_str));
+ GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str));
hpack_enc(c, mdelem, st);
GRPC_MDELEM_UNREF(mdelem);
}
@@ -468,11 +468,8 @@ static gpr_uint32 elems_for_bytes(gpr_uint32 bytes) {
return (bytes + 31) / 32;
}
-void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c,
- grpc_mdctx *ctx) {
+void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c) {
memset(c, 0, sizeof(*c));
- c->mdctx = ctx;
- c->timeout_key_str = grpc_mdstr_from_string(ctx, "grpc-timeout");
c->max_table_size = GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE;
c->cap_table_elems = elems_for_bytes(c->max_table_size);
c->max_table_elems = c->cap_table_elems;
@@ -489,7 +486,6 @@ void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
if (c->entries_keys[i]) GRPC_MDSTR_UNREF(c->entries_keys[i]);
if (c->entries_elems[i]) GRPC_MDELEM_UNREF(c->entries_elems[i]);
}
- GRPC_MDSTR_UNREF(c->timeout_key_str);
gpr_free(c->table_elem_size);
}
diff --git a/src/core/transport/chttp2/hpack_encoder.h b/src/core/transport/chttp2/hpack_encoder.h
index ce83d101f2..a3600436e9 100644
--- a/src/core/transport/chttp2/hpack_encoder.h
+++ b/src/core/transport/chttp2/hpack_encoder.h
@@ -71,11 +71,6 @@ typedef struct {
been seen. When that count reaches max (255), all values are halved. */
gpr_uint8 filter_elems[GRPC_CHTTP2_HPACKC_NUM_FILTERS];
- /* metadata context */
- grpc_mdctx *mdctx;
- /* the string 'grpc-timeout' */
- grpc_mdstr *timeout_key_str;
-
/* 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];
@@ -86,8 +81,7 @@ typedef struct {
gpr_uint16 *table_elem_size;
} grpc_chttp2_hpack_compressor;
-void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c,
- grpc_mdctx *mdctx);
+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_set_max_table_size(
grpc_chttp2_hpack_compressor *c, gpr_uint32 max_table_size);
diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c
index 57a3a20b1d..d38ff68754 100644
--- a/src/core/transport/chttp2/hpack_parser.c
+++ b/src/core/transport/chttp2/hpack_parser.c
@@ -637,8 +637,7 @@ static int on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md,
static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p,
grpc_chttp2_hpack_parser_string *str) {
- grpc_mdstr *s = grpc_mdstr_from_buffer(p->table.mdctx, (gpr_uint8 *)str->str,
- str->length);
+ grpc_mdstr *s = grpc_mdstr_from_buffer((gpr_uint8 *)str->str, str->length);
str->length = 0;
return s;
}
@@ -749,8 +748,7 @@ static int parse_indexed_field_x(grpc_chttp2_hpack_parser *p,
static int finish_lithdr_incidx(grpc_chttp2_hpack_parser *p,
const gpr_uint8 *cur, const gpr_uint8 *end) {
grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
- return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
- GRPC_MDSTR_REF(md->key),
+ return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
take_string(p, &p->value)),
1) &&
parse_begin(p, cur, end);
@@ -759,8 +757,7 @@ static int finish_lithdr_incidx(grpc_chttp2_hpack_parser *p,
/* finish a literal header with incremental indexing with no index */
static int finish_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
const gpr_uint8 *cur, const gpr_uint8 *end) {
- return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
- take_string(p, &p->key),
+ return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
take_string(p, &p->value)),
1) &&
parse_begin(p, cur, end);
@@ -802,8 +799,7 @@ static int parse_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
static int finish_lithdr_notidx(grpc_chttp2_hpack_parser *p,
const gpr_uint8 *cur, const gpr_uint8 *end) {
grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
- return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
- GRPC_MDSTR_REF(md->key),
+ return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
take_string(p, &p->value)),
0) &&
parse_begin(p, cur, end);
@@ -812,8 +808,7 @@ static int finish_lithdr_notidx(grpc_chttp2_hpack_parser *p,
/* finish a literal header without incremental indexing with index = 0 */
static int finish_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
const gpr_uint8 *cur, const gpr_uint8 *end) {
- return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
- take_string(p, &p->key),
+ return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
take_string(p, &p->value)),
0) &&
parse_begin(p, cur, end);
@@ -855,8 +850,7 @@ static int parse_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
static int finish_lithdr_nvridx(grpc_chttp2_hpack_parser *p,
const gpr_uint8 *cur, const gpr_uint8 *end) {
grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
- return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
- GRPC_MDSTR_REF(md->key),
+ return on_hdr(p, grpc_mdelem_from_metadata_strings(GRPC_MDSTR_REF(md->key),
take_string(p, &p->value)),
0) &&
parse_begin(p, cur, end);
@@ -865,8 +859,7 @@ static int finish_lithdr_nvridx(grpc_chttp2_hpack_parser *p,
/* finish a literal header that is never indexed with an extra value */
static int finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
const gpr_uint8 *cur, const gpr_uint8 *end) {
- return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
- take_string(p, &p->key),
+ return on_hdr(p, grpc_mdelem_from_metadata_strings(take_string(p, &p->key),
take_string(p, &p->value)),
0) &&
parse_begin(p, cur, end);
@@ -1356,8 +1349,7 @@ static void on_header_not_set(void *user_data, grpc_mdelem *md) {
abort();
}
-void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p,
- grpc_mdctx *mdctx) {
+void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) {
p->on_header = on_header_not_set;
p->on_header_user_data = NULL;
p->state = parse_begin;
@@ -1367,7 +1359,7 @@ void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p,
p->value.str = NULL;
p->value.capacity = 0;
p->value.length = 0;
- grpc_chttp2_hptbl_init(&p->table, mdctx);
+ grpc_chttp2_hptbl_init(&p->table);
}
void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser *p) {
diff --git a/src/core/transport/chttp2/hpack_parser.h b/src/core/transport/chttp2/hpack_parser.h
index f56867016c..fb894b5735 100644
--- a/src/core/transport/chttp2/hpack_parser.h
+++ b/src/core/transport/chttp2/hpack_parser.h
@@ -95,8 +95,7 @@ struct grpc_chttp2_hpack_parser {
grpc_chttp2_hptbl table;
};
-void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p,
- grpc_mdctx *mdctx);
+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_set_has_priority(grpc_chttp2_hpack_parser *p);
diff --git a/src/core/transport/chttp2/hpack_table.c b/src/core/transport/chttp2/hpack_table.c
index f2362b056c..59060daad3 100644
--- a/src/core/transport/chttp2/hpack_table.c
+++ b/src/core/transport/chttp2/hpack_table.c
@@ -176,11 +176,10 @@ static gpr_uint32 entries_for_bytes(gpr_uint32 bytes) {
GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
}
-void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl, grpc_mdctx *mdctx) {
+void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl) {
size_t i;
memset(tbl, 0, sizeof(*tbl));
- tbl->mdctx = mdctx;
tbl->current_table_bytes = tbl->max_bytes =
GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE;
tbl->max_entries = tbl->cap_entries =
@@ -188,8 +187,8 @@ void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl, grpc_mdctx *mdctx) {
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(
- mdctx, static_table[i].key, static_table[i].value);
+ tbl->static_ents[i - 1] =
+ grpc_mdelem_from_strings(static_table[i].key, static_table[i].value);
}
}
diff --git a/src/core/transport/chttp2/hpack_table.h b/src/core/transport/chttp2/hpack_table.h
index e03b8c19b3..a173eec30c 100644
--- a/src/core/transport/chttp2/hpack_table.h
+++ b/src/core/transport/chttp2/hpack_table.h
@@ -59,7 +59,6 @@
/* hpack decoder table */
typedef struct {
- grpc_mdctx *mdctx;
/* the first used entry in ents */
gpr_uint32 first_ent;
/* how many entries are in the table */
@@ -84,7 +83,7 @@ typedef struct {
} grpc_chttp2_hptbl;
/* initialize a hpack table */
-void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl, grpc_mdctx *mdctx);
+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,
gpr_uint32 max_bytes);
diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h
index b2ac8ee965..3952f8a0e8 100644
--- a/src/core/transport/chttp2/internal.h
+++ b/src/core/transport/chttp2/internal.h
@@ -238,9 +238,6 @@ struct grpc_chttp2_transport_parsing {
/** data to write later - after parsing */
gpr_slice_buffer qbuf;
- /* metadata object cache */
- grpc_mdstr *str_grpc_timeout;
- grpc_mdelem *elem_grpc_status_ok;
/** parser for headers */
grpc_chttp2_hpack_parser hpack_parser;
/** simple one shot parsers */
@@ -294,7 +291,6 @@ struct grpc_chttp2_transport_parsing {
struct grpc_chttp2_transport {
grpc_transport base; /* must be first */
grpc_endpoint *ep;
- grpc_mdctx *metadata_context;
gpr_refcount refs;
char *peer_string;
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index 1e06532c03..467e734cc3 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -35,14 +35,15 @@
#include <string.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
#include "src/core/profiling/timers.h"
#include "src/core/transport/chttp2/http2_errors.h"
#include "src/core/transport/chttp2/status_conversion.h"
#include "src/core/transport/chttp2/timeout_encoding.h"
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
+#include "src/core/transport/static_metadata.h"
static int init_frame_parser(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport_parsing *transport_parsing);
@@ -592,13 +593,12 @@ static void on_initial_header(void *tp, grpc_mdelem *md) {
transport_parsing->is_client ? "CLI" : "SVR",
grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)));
- if (md->key == transport_parsing->elem_grpc_status_ok->key &&
- md != transport_parsing->elem_grpc_status_ok) {
+ if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) {
/* TODO(ctiller): check for a status like " 0" */
stream_parsing->seen_error = 1;
}
- if (md->key == transport_parsing->str_grpc_timeout) {
+ if (md->key == GRPC_MDSTR_GRPC_TIMEOUT) {
gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout);
if (!cached_timeout) {
/* not already parsed: parse it now, and store the result away */
@@ -639,8 +639,7 @@ static void on_trailing_header(void *tp, grpc_mdelem *md) {
transport_parsing->is_client ? "CLI" : "SVR",
grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)));
- if (md->key == transport_parsing->elem_grpc_status_ok->key &&
- md != transport_parsing->elem_grpc_status_ok) {
+ if (md->key == GRPC_MDSTR_GRPC_STATUS && md != GRPC_MDELEM_GRPC_STATUS_0) {
/* TODO(ctiller): check for a status like " 0" */
stream_parsing->seen_error = 1;
}
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 77c68c9df0..97f2a1b75c 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -49,6 +49,7 @@
#include "src/core/transport/chttp2/internal.h"
#include "src/core/transport/chttp2/status_conversion.h"
#include "src/core/transport/chttp2/timeout_encoding.h"
+#include "src/core/transport/static_metadata.h"
#include "src/core/transport/transport_impl.h"
#define DEFAULT_WINDOW 65535
@@ -155,9 +156,6 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_parser_destroy(&t->parsing.hpack_parser);
grpc_chttp2_goaway_parser_destroy(&t->parsing.goaway_parser);
- GRPC_MDSTR_UNREF(t->parsing.str_grpc_timeout);
- GRPC_MDELEM_UNREF(t->parsing.elem_grpc_status_ok);
-
for (i = 0; i < STREAM_LIST_COUNT; i++) {
GPR_ASSERT(t->lists[i].head == NULL);
GPR_ASSERT(t->lists[i].tail == NULL);
@@ -183,8 +181,6 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
gpr_free(ping);
}
- grpc_mdctx_unref(t->metadata_context);
-
gpr_free(t->peer_string);
gpr_free(t);
}
@@ -219,8 +215,7 @@ static void ref_transport(grpc_chttp2_transport *t) { gpr_ref(&t->refs); }
static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
const grpc_channel_args *channel_args,
- grpc_endpoint *ep, grpc_mdctx *mdctx,
- gpr_uint8 is_client) {
+ grpc_endpoint *ep, gpr_uint8 is_client) {
size_t i;
int j;
@@ -236,9 +231,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
/* ref is dropped at transport close() */
gpr_ref_init(&t->shutdown_ep_refs, 1);
gpr_mu_init(&t->mu);
- grpc_mdctx_ref(mdctx);
t->peer_string = grpc_endpoint_get_peer(ep);
- t->metadata_context = mdctx;
t->endpoint_reading = 1;
t->global.next_stream_id = is_client ? 1 : 2;
t->global.is_client = is_client;
@@ -249,10 +242,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->global.ping_counter = 1;
t->global.pings.next = t->global.pings.prev = &t->global.pings;
t->parsing.is_client = is_client;
- t->parsing.str_grpc_timeout =
- grpc_mdstr_from_string(t->metadata_context, "grpc-timeout");
- t->parsing.elem_grpc_status_ok =
- grpc_mdelem_from_strings(t->metadata_context, "grpc-status", "0");
t->parsing.deframe_state =
is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
t->writing.is_client = is_client;
@@ -263,12 +252,12 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
gpr_slice_buffer_init(&t->global.qbuf);
gpr_slice_buffer_init(&t->writing.outbuf);
- grpc_chttp2_hpack_compressor_init(&t->writing.hpack_compressor, mdctx);
+ grpc_chttp2_hpack_compressor_init(&t->writing.hpack_compressor);
grpc_closure_init(&t->writing_action, writing_action, t);
gpr_slice_buffer_init(&t->parsing.qbuf);
grpc_chttp2_goaway_parser_init(&t->parsing.goaway_parser);
- grpc_chttp2_hpack_parser_init(&t->parsing.hpack_parser, t->metadata_context);
+ grpc_chttp2_hpack_parser_init(&t->parsing.hpack_parser);
grpc_closure_init(&t->writing.done_cb, grpc_chttp2_terminate_writing,
&t->writing);
@@ -762,11 +751,10 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
static int contains_non_ok_status(
grpc_chttp2_transport_global *transport_global,
grpc_metadata_batch *batch) {
- grpc_mdelem *ok_elem =
- TRANSPORT_FROM_GLOBAL(transport_global)->parsing.elem_grpc_status_ok;
grpc_linked_mdelem *l;
for (l = batch->list.head; l; l = l->next) {
- if (l->md->key == ok_elem->key && l->md != ok_elem) {
+ if (l->md->key == GRPC_MDSTR_GRPC_STATUS &&
+ l->md != GRPC_MDELEM_GRPC_STATUS_0) {
return 1;
}
}
@@ -1078,19 +1066,18 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx,
about the metadata yet */
if (!stream_global->published_trailing_metadata ||
stream_global->recv_trailing_metadata_finished != NULL) {
- grpc_mdctx *mdctx =
- TRANSPORT_FROM_GLOBAL(transport_global)->metadata_context;
char status_string[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(status, status_string);
grpc_chttp2_incoming_metadata_buffer_add(
&stream_global->received_trailing_metadata,
- grpc_mdelem_from_strings(mdctx, "grpc-status", status_string));
+ grpc_mdelem_from_metadata_strings(
+ GRPC_MDSTR_GRPC_STATUS, grpc_mdstr_from_string(status_string)));
if (slice) {
grpc_chttp2_incoming_metadata_buffer_add(
&stream_global->received_trailing_metadata,
grpc_mdelem_from_metadata_strings(
- mdctx, grpc_mdstr_from_string(mdctx, "grpc-message"),
- grpc_mdstr_from_slice(mdctx, gpr_slice_ref(*slice))));
+ GRPC_MDSTR_GRPC_MESSAGE,
+ grpc_mdstr_from_slice(gpr_slice_ref(*slice))));
}
stream_global->published_trailing_metadata = 1;
grpc_chttp2_list_add_check_read_ops(transport_global, stream_global);
@@ -1641,9 +1628,9 @@ static const grpc_transport_vtable vtable = {
grpc_transport *grpc_create_chttp2_transport(
grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args,
- grpc_endpoint *ep, grpc_mdctx *mdctx, int is_client) {
+ grpc_endpoint *ep, int is_client) {
grpc_chttp2_transport *t = gpr_malloc(sizeof(grpc_chttp2_transport));
- init_transport(exec_ctx, t, channel_args, ep, mdctx, is_client != 0);
+ init_transport(exec_ctx, t, channel_args, ep, is_client != 0);
return &t->base;
}
diff --git a/src/core/transport/chttp2_transport.h b/src/core/transport/chttp2_transport.h
index fce2b680fd..95520501ed 100644
--- a/src/core/transport/chttp2_transport.h
+++ b/src/core/transport/chttp2_transport.h
@@ -42,7 +42,7 @@ extern int grpc_flowctl_trace;
grpc_transport *grpc_create_chttp2_transport(
grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args,
- grpc_endpoint *ep, grpc_mdctx *metadata_context, int is_client);
+ grpc_endpoint *ep, int is_client);
void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx,
grpc_transport *transport,
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index a72dee4399..a76d1ad3a5 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -31,20 +31,32 @@
*
*/
-#include "src/core/iomgr/sockaddr.h"
#include "src/core/transport/metadata.h"
#include <assert.h>
#include <stddef.h>
#include <string.h>
+#include <grpc/compression.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include "src/core/profiling/timers.h"
#include "src/core/support/murmur_hash.h"
+#include "src/core/support/string.h"
#include "src/core/transport/chttp2/bin_encoder.h"
+#include "src/core/transport/static_metadata.h"
+
+/* 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().
+ * Dynamic instances are stored in hash tables on grpc_mdctx, and are backed
+ * by internal_string and internal_element structures.
+ * Internal helper functions here-in (is_mdstr_static, is_mdelem_static) are
+ * used to determine which kind of element a pointer refers to.
+ */
#define INITIAL_STRTAB_CAPACITY 4
#define INITIAL_MDTAB_CAPACITY 4
@@ -52,107 +64,186 @@
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
#define DEBUG_ARGS , const char *file, int line
#define FWD_DEBUG_ARGS , file, line
-#define INTERNAL_STRING_REF(s) internal_string_ref((s), __FILE__, __LINE__)
-#define INTERNAL_STRING_UNREF(s) internal_string_unref((s), __FILE__, __LINE__)
-#define REF_MD_LOCKED(s) ref_md_locked((s), __FILE__, __LINE__)
+#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s), __FILE__, __LINE__)
#else
#define DEBUG_ARGS
#define FWD_DEBUG_ARGS
-#define INTERNAL_STRING_REF(s) internal_string_ref((s))
-#define INTERNAL_STRING_UNREF(s) internal_string_unref((s))
-#define REF_MD_LOCKED(s) ref_md_locked((s))
+#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);
+/* Shadow structure for grpc_mdstr for non-static values */
typedef struct internal_string {
/* must be byte compatible with grpc_mdstr */
gpr_slice slice;
gpr_uint32 hash;
/* private only data */
- gpr_uint32 refs;
+ gpr_atm refcnt;
+
gpr_uint8 has_base64_and_huffman_encoded;
gpr_slice_refcount refcount;
gpr_slice base64_and_huffman;
- grpc_mdctx *context;
-
struct internal_string *bucket_next;
} internal_string;
+/* 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;
+ /* private only data */
gpr_atm refcnt;
- /* private only data */
gpr_mu mu_user_data;
gpr_atm destroy_user_data;
gpr_atm user_data;
- grpc_mdctx *context;
struct internal_metadata *bucket_next;
} internal_metadata;
-struct grpc_mdctx {
- gpr_uint32 hash_seed;
- int refs;
-
+typedef struct strtab_shard {
gpr_mu mu;
+ internal_string **strs;
+ size_t count;
+ size_t capacity;
+} strtab_shard;
- internal_string **strtab;
- size_t strtab_count;
- size_t strtab_capacity;
+typedef struct mdtab_shard {
+ gpr_mu mu;
+ internal_metadata **elems;
+ size_t count;
+ size_t capacity;
+ size_t free;
+} 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 gpr_uint32 g_hash_seed;
+
+/* 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_mdctx_global_init(void) {
+ size_t i, j;
+ g_hash_seed = (gpr_uint32)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];
+ gpr_uint32 hash = gpr_murmur_hash3(str, strlen(str), g_hash_seed);
+ *(gpr_slice *)&elem->slice = gpr_slice_from_static_string(str);
+ *(gpr_uint32 *)&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]];
+ gpr_uint32 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];
+ gpr_mu_init(&shard->mu);
+ shard->count = 0;
+ shard->free = 0;
+ shard->capacity = INITIAL_MDTAB_CAPACITY;
+ shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity);
+ memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity);
+ }
+}
- internal_metadata **mdtab;
- size_t mdtab_count;
- size_t mdtab_free;
- size_t mdtab_capacity;
-};
-
-static void internal_string_ref(internal_string *s DEBUG_ARGS);
-static void internal_string_unref(internal_string *s DEBUG_ARGS);
-static void discard_metadata(grpc_mdctx *ctx);
-static void gc_mdtab(grpc_mdctx *ctx);
-static void metadata_context_destroy_locked(grpc_mdctx *ctx);
-
-static void lock(grpc_mdctx *ctx) { gpr_mu_lock(&ctx->mu); }
-
-static void unlock(grpc_mdctx *ctx) {
- /* If the context has been orphaned we'd like to delete it soon. We check
- conditions in unlock as it signals the end of mutations on a context.
-
- We need to ensure all grpc_mdelem and grpc_mdstr elements have been deleted
- first. This is equivalent to saying that both tables have zero counts,
- which is equivalent to saying that strtab_count is zero (as mdelem's MUST
- reference an mdstr for their key and value slots).
-
- To encourage that to happen, we start discarding zero reference count
- mdelems on every unlock (instead of the usual 'I'm too loaded' trigger
- case), since otherwise we can be stuck waiting for a garbage collection
- that will never happen. */
- if (ctx->refs == 0) {
-/* uncomment if you're having trouble diagnosing an mdelem leak to make
- things clearer (slows down destruction a lot, however) */
-#ifdef GRPC_METADATA_REFCOUNT_DEBUG
- gc_mdtab(ctx);
-#endif
- if (ctx->mdtab_count && ctx->mdtab_count == ctx->mdtab_free) {
- discard_metadata(ctx);
+void grpc_mdctx_global_shutdown(void) {
+ size_t i;
+ for (i = 0; i < MDTAB_SHARD_COUNT; i++) {
+ mdtab_shard *shard = &g_mdtab_shard[i];
+ gpr_mu_destroy(&shard->mu);
+ gc_mdtab(shard);
+ /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
+ if (shard->count != 0) {
+ gpr_log(GPR_DEBUG, "WARNING: %d metadata elements were leaked", shard->count);
}
- if (ctx->strtab_count == 0) {
- metadata_context_destroy_locked(ctx);
- return;
+ 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: %d metadata strings were leaked", shard->count);
}
+ gpr_free(shard->strs);
}
- gpr_mu_unlock(&ctx->mu);
}
-static void ref_md_locked(internal_metadata *md DEBUG_ARGS) {
+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 void ref_md_locked(mdtab_shard *shard,
+ internal_metadata *md DEBUG_ARGS) {
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"ELM REF:%p:%d->%d: '%s' = '%s'", md,
@@ -162,96 +253,14 @@ static void ref_md_locked(internal_metadata *md DEBUG_ARGS) {
grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
#endif
if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 2)) {
- md->context->mdtab_free--;
+ shard->free--;
} else {
GPR_ASSERT(1 != gpr_atm_no_barrier_fetch_add(&md->refcnt, -1));
}
}
-grpc_mdctx *grpc_mdctx_create_with_seed(gpr_uint32 seed) {
- grpc_mdctx *ctx = gpr_malloc(sizeof(grpc_mdctx));
-
- ctx->refs = 1;
- ctx->hash_seed = seed;
- gpr_mu_init(&ctx->mu);
- ctx->strtab = gpr_malloc(sizeof(internal_string *) * INITIAL_STRTAB_CAPACITY);
- memset(ctx->strtab, 0, sizeof(grpc_mdstr *) * INITIAL_STRTAB_CAPACITY);
- ctx->strtab_count = 0;
- ctx->strtab_capacity = INITIAL_STRTAB_CAPACITY;
- ctx->mdtab = gpr_malloc(sizeof(internal_metadata *) * INITIAL_MDTAB_CAPACITY);
- memset(ctx->mdtab, 0, sizeof(grpc_mdelem *) * INITIAL_MDTAB_CAPACITY);
- ctx->mdtab_count = 0;
- ctx->mdtab_capacity = INITIAL_MDTAB_CAPACITY;
- ctx->mdtab_free = 0;
-
- return ctx;
-}
-
-grpc_mdctx *grpc_mdctx_create(void) {
- /* This seed is used to prevent remote connections from controlling hash table
- * collisions. It needs to be somewhat unpredictable to a remote connection.
- */
- return grpc_mdctx_create_with_seed(
- (gpr_uint32)gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
-}
-
-static void discard_metadata(grpc_mdctx *ctx) {
- size_t i;
- internal_metadata *next, *cur;
-
- for (i = 0; i < ctx->mdtab_capacity; i++) {
- cur = ctx->mdtab[i];
- while (cur) {
- void *user_data = (void *)gpr_atm_no_barrier_load(&cur->user_data);
- GPR_ASSERT(gpr_atm_acq_load(&cur->refcnt) == 0);
- next = cur->bucket_next;
- INTERNAL_STRING_UNREF(cur->key);
- INTERNAL_STRING_UNREF(cur->value);
- if (user_data != NULL) {
- ((destroy_user_data_func)gpr_atm_no_barrier_load(
- &cur->destroy_user_data))(user_data);
- }
- gpr_mu_destroy(&cur->mu_user_data);
- gpr_free(cur);
- cur = next;
- ctx->mdtab_free--;
- ctx->mdtab_count--;
- }
- ctx->mdtab[i] = NULL;
- }
-}
-
-static void metadata_context_destroy_locked(grpc_mdctx *ctx) {
- GPR_ASSERT(ctx->strtab_count == 0);
- GPR_ASSERT(ctx->mdtab_count == 0);
- GPR_ASSERT(ctx->mdtab_free == 0);
- gpr_free(ctx->strtab);
- gpr_free(ctx->mdtab);
- gpr_mu_unlock(&ctx->mu);
- gpr_mu_destroy(&ctx->mu);
- gpr_free(ctx);
-}
-
-void grpc_mdctx_ref(grpc_mdctx *ctx) {
- GPR_TIMER_BEGIN("grpc_mdctx_ref", 0);
- lock(ctx);
- GPR_ASSERT(ctx->refs > 0);
- ctx->refs++;
- unlock(ctx);
- GPR_TIMER_END("grpc_mdctx_ref", 0);
-}
-
-void grpc_mdctx_unref(grpc_mdctx *ctx) {
- GPR_TIMER_BEGIN("grpc_mdctx_unref", 0);
- lock(ctx);
- GPR_ASSERT(ctx->refs > 0);
- ctx->refs--;
- unlock(ctx);
- GPR_TIMER_END("grpc_mdctx_unref", 0);
-}
-
-static void grow_strtab(grpc_mdctx *ctx) {
- size_t capacity = ctx->strtab_capacity * 2;
+static void grow_strtab(strtab_shard *shard) {
+ size_t capacity = shard->capacity * 2;
size_t i;
internal_string **strtab;
internal_string *s, *next;
@@ -261,105 +270,95 @@ static void grow_strtab(grpc_mdctx *ctx) {
strtab = gpr_malloc(sizeof(internal_string *) * capacity);
memset(strtab, 0, sizeof(internal_string *) * capacity);
- for (i = 0; i < ctx->strtab_capacity; i++) {
- for (s = ctx->strtab[i]; s; s = next) {
+ 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[s->hash % capacity];
- strtab[s->hash % capacity] = s;
+ s->bucket_next = strtab[idx];
+ strtab[idx] = s;
}
}
- gpr_free(ctx->strtab);
- ctx->strtab = strtab;
- ctx->strtab_capacity = capacity;
+ gpr_free(shard->strs);
+ shard->strs = strtab;
+ shard->capacity = capacity;
GPR_TIMER_END("grow_strtab", 0);
}
-static void internal_destroy_string(internal_string *is) {
+static void internal_destroy_string(strtab_shard *shard, internal_string *is) {
internal_string **prev_next;
internal_string *cur;
- grpc_mdctx *ctx = is->context;
GPR_TIMER_BEGIN("internal_destroy_string", 0);
if (is->has_base64_and_huffman_encoded) {
gpr_slice_unref(is->base64_and_huffman);
}
- for (prev_next = &ctx->strtab[is->hash % ctx->strtab_capacity],
+ 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;
- ctx->strtab_count--;
+ shard->count--;
gpr_free(is);
GPR_TIMER_END("internal_destroy_string", 0);
}
-static void internal_string_ref(internal_string *s DEBUG_ARGS) {
-#ifdef GRPC_METADATA_REFCOUNT_DEBUG
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "STR REF:%p:%d->%d: '%s'", s,
- s->refs, s->refs + 1, grpc_mdstr_as_c_string((grpc_mdstr *)s));
-#endif
- ++s->refs;
-}
-
-static void internal_string_unref(internal_string *s DEBUG_ARGS) {
-#ifdef GRPC_METADATA_REFCOUNT_DEBUG
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "STR UNREF:%p:%d->%d: '%s'", s,
- s->refs, s->refs - 1, grpc_mdstr_as_c_string((grpc_mdstr *)s));
-#endif
- GPR_ASSERT(s->refs > 0);
- if (0 == --s->refs) {
- internal_destroy_string(s);
- }
-}
-
static void slice_ref(void *p) {
internal_string *is =
(internal_string *)((char *)p - offsetof(internal_string, refcount));
- grpc_mdctx *ctx = is->context;
- GPR_TIMER_BEGIN("slice_ref", 0);
- lock(ctx);
- INTERNAL_STRING_REF(is);
- unlock(ctx);
- GPR_TIMER_END("slice_ref", 0);
+ GRPC_MDSTR_REF((grpc_mdstr *)(is));
}
static void slice_unref(void *p) {
internal_string *is =
(internal_string *)((char *)p - offsetof(internal_string, refcount));
- grpc_mdctx *ctx = is->context;
- GPR_TIMER_BEGIN("slice_unref", 0);
- lock(ctx);
- INTERNAL_STRING_UNREF(is);
- unlock(ctx);
- GPR_TIMER_END("slice_unref", 0);
+ GRPC_MDSTR_UNREF((grpc_mdstr *)(is));
}
-grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str) {
- return grpc_mdstr_from_buffer(ctx, (const gpr_uint8 *)str, strlen(str));
+grpc_mdstr *grpc_mdstr_from_string(const char *str) {
+ return grpc_mdstr_from_buffer((const gpr_uint8 *)str, strlen(str));
}
-grpc_mdstr *grpc_mdstr_from_slice(grpc_mdctx *ctx, gpr_slice slice) {
- grpc_mdstr *result = grpc_mdstr_from_buffer(ctx, GPR_SLICE_START_PTR(slice),
+grpc_mdstr *grpc_mdstr_from_slice(gpr_slice slice) {
+ grpc_mdstr *result = grpc_mdstr_from_buffer(GPR_SLICE_START_PTR(slice),
GPR_SLICE_LENGTH(slice));
gpr_slice_unref(slice);
return result;
}
-grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *buf,
- size_t length) {
- gpr_uint32 hash = gpr_murmur_hash3(buf, length, ctx->hash_seed);
+grpc_mdstr *grpc_mdstr_from_buffer(const gpr_uint8 *buf, size_t length) {
+ gpr_uint32 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);
- lock(ctx);
+
+ /* 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 && GPR_SLICE_LENGTH(ss->slice) == length &&
+ 0 == memcmp(buf, GPR_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 */
- for (s = ctx->strtab[hash % ctx->strtab_capacity]; s; s = s->bucket_next) {
+ idx = TABLE_IDX(hash, LOG2_STRTAB_SHARD_COUNT, shard->capacity);
+ for (s = shard->strs[idx]; s; s = s->bucket_next) {
if (s->hash == hash && GPR_SLICE_LENGTH(s->slice) == length &&
0 == memcmp(buf, GPR_SLICE_START_PTR(s->slice), length)) {
- INTERNAL_STRING_REF(s);
- unlock(ctx);
+ GRPC_MDSTR_REF((grpc_mdstr *)s);
+ gpr_mu_unlock(&shard->mu);
GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
return (grpc_mdstr *)s;
}
@@ -369,7 +368,7 @@ grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *buf,
if (length + 1 < GPR_SLICE_INLINED_SIZE) {
/* string data goes directly into the slice */
s = gpr_malloc(sizeof(internal_string));
- s->refs = 1;
+ gpr_atm_rel_store(&s->refcnt, 2);
s->slice.refcount = NULL;
memcpy(s->slice.data.inlined.bytes, buf, length);
s->slice.data.inlined.bytes[length] = 0;
@@ -378,7 +377,7 @@ grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *buf,
/* string data goes after the internal_string header, and we +1 for null
terminator */
s = gpr_malloc(sizeof(internal_string) + length + 1);
- s->refs = 1;
+ gpr_atm_rel_store(&s->refcnt, 2);
s->refcount.ref = slice_ref;
s->refcount.unref = slice_unref;
s->slice.refcount = &s->refcount;
@@ -390,44 +389,43 @@ grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *buf,
}
s->has_base64_and_huffman_encoded = 0;
s->hash = hash;
- s->context = ctx;
- s->bucket_next = ctx->strtab[hash % ctx->strtab_capacity];
- ctx->strtab[hash % ctx->strtab_capacity] = s;
+ s->bucket_next = shard->strs[idx];
+ shard->strs[idx] = s;
- ctx->strtab_count++;
+ shard->count++;
- if (ctx->strtab_count > ctx->strtab_capacity * 2) {
- grow_strtab(ctx);
+ if (shard->count > shard->capacity * 2) {
+ grow_strtab(shard);
}
- unlock(ctx);
+ gpr_mu_unlock(&shard->mu);
GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
return (grpc_mdstr *)s;
}
-static void gc_mdtab(grpc_mdctx *ctx) {
+static void gc_mdtab(mdtab_shard *shard) {
size_t i;
internal_metadata **prev_next;
internal_metadata *md, *next;
GPR_TIMER_BEGIN("gc_mdtab", 0);
- for (i = 0; i < ctx->mdtab_capacity; i++) {
- prev_next = &ctx->mdtab[i];
- for (md = ctx->mdtab[i]; md; md = next) {
+ for (i = 0; i < shard->capacity; i++) {
+ prev_next = &shard->elems[i];
+ for (md = shard->elems[i]; md; md = next) {
void *user_data = (void *)gpr_atm_no_barrier_load(&md->user_data);
next = md->bucket_next;
if (gpr_atm_acq_load(&md->refcnt) == 0) {
- INTERNAL_STRING_UNREF(md->key);
- INTERNAL_STRING_UNREF(md->value);
+ GRPC_MDSTR_UNREF((grpc_mdstr *)md->key);
+ GRPC_MDSTR_UNREF((grpc_mdstr *)md->value);
if (md->user_data) {
((destroy_user_data_func)gpr_atm_no_barrier_load(
&md->destroy_user_data))(user_data);
}
gpr_free(md);
*prev_next = next;
- ctx->mdtab_free--;
- ctx->mdtab_count--;
+ shard->free--;
+ shard->count--;
} else {
prev_next = &md->bucket_next;
}
@@ -436,8 +434,8 @@ static void gc_mdtab(grpc_mdctx *ctx) {
GPR_TIMER_END("gc_mdtab", 0);
}
-static void grow_mdtab(grpc_mdctx *ctx) {
- size_t capacity = ctx->mdtab_capacity * 2;
+static void grow_mdtab(mdtab_shard *shard) {
+ size_t capacity = shard->capacity * 2;
size_t i;
internal_metadata **mdtab;
internal_metadata *md, *next;
@@ -448,52 +446,67 @@ static void grow_mdtab(grpc_mdctx *ctx) {
mdtab = gpr_malloc(sizeof(internal_metadata *) * capacity);
memset(mdtab, 0, sizeof(internal_metadata *) * capacity);
- for (i = 0; i < ctx->mdtab_capacity; i++) {
- for (md = ctx->mdtab[i]; md; md = next) {
+ 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);
next = md->bucket_next;
- md->bucket_next = mdtab[hash % capacity];
- mdtab[hash % capacity] = md;
+ idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, capacity);
+ md->bucket_next = mdtab[idx];
+ mdtab[idx] = md;
}
}
- gpr_free(ctx->mdtab);
- ctx->mdtab = mdtab;
- ctx->mdtab_capacity = capacity;
+ gpr_free(shard->elems);
+ shard->elems = mdtab;
+ shard->capacity = capacity;
GPR_TIMER_END("grow_mdtab", 0);
}
-static void rehash_mdtab(grpc_mdctx *ctx) {
- if (ctx->mdtab_free > ctx->mdtab_capacity / 4) {
- gc_mdtab(ctx);
+static void rehash_mdtab(mdtab_shard *shard) {
+ if (shard->free > shard->capacity / 4) {
+ gc_mdtab(shard);
} else {
- grow_mdtab(ctx);
+ grow_mdtab(shard);
}
}
-grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx,
- grpc_mdstr *mkey,
+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;
gpr_uint32 hash = GRPC_MDSTR_KV_HASH(mkey->hash, mvalue->hash);
internal_metadata *md;
-
- GPR_ASSERT(key->context == ctx);
- GPR_ASSERT(value->context == ctx);
+ mdtab_shard *shard = &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)];
+ size_t i;
+ size_t idx;
GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0);
- lock(ctx);
+ 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;
+ }
+ }
+ }
+
+ gpr_mu_lock(&shard->mu);
+ idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, shard->capacity);
/* search for an existing pair */
- for (md = ctx->mdtab[hash % ctx->mdtab_capacity]; md; md = md->bucket_next) {
+ for (md = shard->elems[idx]; md; md = md->bucket_next) {
if (md->key == key && md->value == value) {
- REF_MD_LOCKED(md);
- INTERNAL_STRING_UNREF(key);
- INTERNAL_STRING_UNREF(value);
- unlock(ctx);
+ 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;
}
@@ -502,12 +515,12 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx,
/* not found: create a new pair */
md = gpr_malloc(sizeof(internal_metadata));
gpr_atm_rel_store(&md->refcnt, 2);
- md->context = ctx;
md->key = key;
md->value = value;
md->user_data = 0;
md->destroy_user_data = 0;
- md->bucket_next = ctx->mdtab[hash % ctx->mdtab_capacity];
+ md->bucket_next = shard->elems[idx];
+ shard->elems[idx] = md;
gpr_mu_init(&md->mu_user_data);
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
gpr_log(GPR_DEBUG, "ELM NEW:%p:%d: '%s' = '%s'", md,
@@ -515,44 +528,39 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx,
grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
#endif
- ctx->mdtab[hash % ctx->mdtab_capacity] = md;
- ctx->mdtab_count++;
+ shard->count++;
- if (ctx->mdtab_count > ctx->mdtab_capacity * 2) {
- rehash_mdtab(ctx);
+ if (shard->count > shard->capacity * 2) {
+ rehash_mdtab(shard);
}
- unlock(ctx);
+ gpr_mu_unlock(&shard->mu);
GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
return (grpc_mdelem *)md;
}
-grpc_mdelem *grpc_mdelem_from_strings(grpc_mdctx *ctx, const char *key,
- const char *value) {
- return grpc_mdelem_from_metadata_strings(ctx,
- grpc_mdstr_from_string(ctx, key),
- grpc_mdstr_from_string(ctx, value));
+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));
}
-grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
- gpr_slice value) {
- return grpc_mdelem_from_metadata_strings(ctx, grpc_mdstr_from_slice(ctx, key),
- grpc_mdstr_from_slice(ctx, value));
+grpc_mdelem *grpc_mdelem_from_slices(gpr_slice key, gpr_slice value) {
+ return grpc_mdelem_from_metadata_strings(grpc_mdstr_from_slice(key),
+ grpc_mdstr_from_slice(value));
}
-grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_mdctx *ctx,
- const char *key,
+grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
const gpr_uint8 *value,
size_t value_length) {
return grpc_mdelem_from_metadata_strings(
- ctx, grpc_mdstr_from_string(ctx, key),
- grpc_mdstr_from_buffer(ctx, value, value_length));
+ grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length));
}
grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) {
internal_metadata *md = (internal_metadata *)gmd;
+ if (is_mdelem_static(gmd)) return gmd;
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"ELM REF:%p:%d->%d: '%s' = '%s'", md,
@@ -573,6 +581,7 @@ grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) {
void grpc_mdelem_unref(grpc_mdelem *gmd DEBUG_ARGS) {
internal_metadata *md = (internal_metadata *)gmd;
if (!md) return;
+ if (is_mdelem_static(gmd)) return;
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"ELM UNREF:%p:%d->%d: '%s' = '%s'", md,
@@ -582,14 +591,16 @@ void grpc_mdelem_unref(grpc_mdelem *gmd DEBUG_ARGS) {
grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
#endif
if (2 == gpr_atm_full_fetch_add(&md->refcnt, -1)) {
- grpc_mdctx *ctx = md->context;
+ gpr_uint32 hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash);
+ mdtab_shard *shard =
+ &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)];
GPR_TIMER_BEGIN("grpc_mdelem_unref.to_zero", 0);
- lock(ctx);
+ gpr_mu_lock(&shard->mu);
if (1 == gpr_atm_no_barrier_load(&md->refcnt)) {
- ctx->mdtab_free++;
+ shard->free++;
gpr_atm_no_barrier_store(&md->refcnt, 0);
}
- unlock(ctx);
+ gpr_mu_unlock(&shard->mu);
GPR_TIMER_END("grpc_mdelem_unref.to_zero", 0);
}
}
@@ -600,36 +611,31 @@ const char *grpc_mdstr_as_c_string(grpc_mdstr *s) {
grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *gs DEBUG_ARGS) {
internal_string *s = (internal_string *)gs;
- grpc_mdctx *ctx = s->context;
- lock(ctx);
- internal_string_ref(s FWD_DEBUG_ARGS);
- unlock(ctx);
+ if (is_mdstr_static(gs)) return gs;
+ 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;
- grpc_mdctx *ctx = s->context;
- lock(ctx);
- internal_string_unref(s FWD_DEBUG_ARGS);
- unlock(ctx);
-}
-
-size_t grpc_mdctx_get_mdtab_capacity_test_only(grpc_mdctx *ctx) {
- return ctx->mdtab_capacity;
-}
-
-size_t grpc_mdctx_get_mdtab_count_test_only(grpc_mdctx *ctx) {
- return ctx->mdtab_count;
-}
-
-size_t grpc_mdctx_get_mdtab_free_test_only(grpc_mdctx *ctx) {
- return ctx->mdtab_free;
+ if (is_mdstr_static(gs)) return;
+ if (2 == 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);
+ if (1 == gpr_atm_no_barrier_load(&s->refcnt)) {
+ internal_destroy_string(shard, s);
+ }
+ gpr_mu_unlock(&shard->mu);
+ }
}
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 {
@@ -641,6 +647,7 @@ void *grpc_mdelem_get_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)) {
@@ -659,15 +666,16 @@ void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) {
internal_string *s = (internal_string *)gs;
gpr_slice slice;
- grpc_mdctx *ctx = s->context;
- lock(ctx);
+ 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;
- unlock(ctx);
+ gpr_mu_unlock(&shard->mu);
return slice;
}
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
index 9a8164037c..c1071e4e16 100644
--- a/src/core/transport/metadata.h
+++ b/src/core/transport/metadata.h
@@ -59,10 +59,15 @@
grpc_mdelem instances MAY live longer than their refcount implies, and are
garbage collected periodically, meaning cached data can easily outlive a
- single request. */
+ single request.
+
+ STATIC METADATA: in static_metadata.h we declare a set of static metadata.
+ These mdelems and mdstrs are available via pre-declared code generated macros
+ and are available to code anywhere between grpc_init() and grpc_shutdown().
+ They are not refcounted, but can be passed to _ref and _unref functions
+ declared here - in which case those functions are effectively no-ops. */
/* Forward declarations */
-typedef struct grpc_mdctx grpc_mdctx;
typedef struct grpc_mdstr grpc_mdstr;
typedef struct grpc_mdelem grpc_mdelem;
@@ -81,25 +86,18 @@ struct grpc_mdelem {
/* there is a private part to this in metadata.c */
};
-/* Create/orphan a metadata context */
-grpc_mdctx *grpc_mdctx_create(void);
-grpc_mdctx *grpc_mdctx_create_with_seed(gpr_uint32 seed);
-void grpc_mdctx_ref(grpc_mdctx *mdctx);
-void grpc_mdctx_unref(grpc_mdctx *mdctx);
-
/* Test only accessors to internal state - only for testing this code - do not
rely on it outside of metadata_test.c */
-size_t grpc_mdctx_get_mdtab_capacity_test_only(grpc_mdctx *mdctx);
-size_t grpc_mdctx_get_mdtab_count_test_only(grpc_mdctx *mdctx);
-size_t grpc_mdctx_get_mdtab_free_test_only(grpc_mdctx *mdctx);
+size_t grpc_mdctx_get_mdtab_capacity_test_only(void);
+size_t grpc_mdctx_get_mdtab_count_test_only(void);
+size_t grpc_mdctx_get_mdtab_free_test_only(void);
/* Constructors for grpc_mdstr instances; take a variety of data types that
clients may have handy */
-grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str);
+grpc_mdstr *grpc_mdstr_from_string(const char *str);
/* Unrefs the slice. */
-grpc_mdstr *grpc_mdstr_from_slice(grpc_mdctx *ctx, gpr_slice slice);
-grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *str,
- size_t length);
+grpc_mdstr *grpc_mdstr_from_slice(gpr_slice slice);
+grpc_mdstr *grpc_mdstr_from_buffer(const gpr_uint8 *str, size_t length);
/* Returns a borrowed slice from the mdstr with its contents base64 encoded
and huffman compressed */
@@ -107,15 +105,12 @@ gpr_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *str);
/* Constructors for grpc_mdelem instances; take a variety of data types that
clients may have handy */
-grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx, grpc_mdstr *key,
+grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *key,
grpc_mdstr *value);
-grpc_mdelem *grpc_mdelem_from_strings(grpc_mdctx *ctx, const char *key,
- const char *value);
+grpc_mdelem *grpc_mdelem_from_strings(const char *key, const char *value);
/* Unrefs the slices. */
-grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
- gpr_slice value);
-grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_mdctx *ctx,
- const char *key,
+grpc_mdelem *grpc_mdelem_from_slices(gpr_slice key, gpr_slice value);
+grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
const gpr_uint8 *value,
size_t value_length);
@@ -157,4 +152,7 @@ int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s);
#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);
+
#endif /* GRPC_INTERNAL_CORE_TRANSPORT_METADATA_H */
diff --git a/src/core/transport/static_metadata.c b/src/core/transport/static_metadata.c
new file mode 100644
index 0000000000..e7aff325c2
--- /dev/null
+++ b/src/core/transport/static_metadata.c
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+/*
+ * WARNING: Auto-generated code.
+ *
+ * To make changes to this file, change
+ * tools/codegen/core/gen_static_metadata.py,
+ * and then re-run it.
+ *
+ * See metadata.h for an explanation of the interface here, and metadata.c for
+ * an
+ * explanation of what's going on.
+ */
+
+#include "src/core/transport/static_metadata.h"
+
+grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
+
+grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
+gpr_uintptr 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, 3, 7, 5, 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};
+
+const gpr_uint8
+ grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] = {
+ 11, 33, 10, 33, 12, 33, 12, 47, 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, 46, 40, 51, 40, 52, 40, 53, 40, 54, 41, 31, 41, 46, 41, 51,
+ 44, 0, 44, 1, 44, 2, 48, 33, 55, 33, 56, 33, 57, 33, 58, 33, 59, 33,
+ 60, 33, 61, 33, 62, 33, 63, 33, 64, 38, 64, 66, 65, 76, 65, 77, 67, 33,
+ 68, 33, 69, 33, 70, 33, 71, 33, 72, 33, 73, 39, 73, 49, 73, 50, 74, 33,
+ 75, 33, 78, 3, 78, 4, 78, 5, 78, 6, 78, 7, 78, 8, 78, 9, 79, 33,
+ 80, 81, 82, 33, 83, 33, 84, 33, 85, 33, 86, 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-status",
+ "grpc-timeout",
+ "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",
+ "link",
+ "location",
+ "max-forwards",
+ ":method",
+ ":path",
+ "POST",
+ "proxy-authenticate",
+ "proxy-authorization",
+ "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"};
+
+const gpr_uint8 grpc_static_accept_encoding_metadata[8] = {0, 29, 26, 30,
+ 28, 32, 27, 31};
diff --git a/src/core/transport/static_metadata.h b/src/core/transport/static_metadata.h
new file mode 100644
index 0000000000..e9055fb45c
--- /dev/null
+++ b/src/core/transport/static_metadata.h
@@ -0,0 +1,402 @@
+/*
+ * 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.
+ */
+
+/*
+ * WARNING: Auto-generated code.
+ *
+ * To make changes to this file, change
+ * tools/codegen/core/gen_static_metadata.py,
+ * and then re-run it.
+ *
+ * See metadata.h for an explanation of the interface here, and metadata.c for
+ * an
+ * explanation of what's going on.
+ */
+
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H
+
+#include "src/core/transport/metadata.h"
+
+#define GRPC_STATIC_MDSTR_COUNT 87
+extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
+/* "0" */
+#define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0])
+/* "1" */
+#define GRPC_MDSTR_1 (&grpc_static_mdstr_table[1])
+/* "2" */
+#define GRPC_MDSTR_2 (&grpc_static_mdstr_table[2])
+/* "200" */
+#define GRPC_MDSTR_200 (&grpc_static_mdstr_table[3])
+/* "204" */
+#define GRPC_MDSTR_204 (&grpc_static_mdstr_table[4])
+/* "206" */
+#define GRPC_MDSTR_206 (&grpc_static_mdstr_table[5])
+/* "304" */
+#define GRPC_MDSTR_304 (&grpc_static_mdstr_table[6])
+/* "400" */
+#define GRPC_MDSTR_400 (&grpc_static_mdstr_table[7])
+/* "404" */
+#define GRPC_MDSTR_404 (&grpc_static_mdstr_table[8])
+/* "500" */
+#define GRPC_MDSTR_500 (&grpc_static_mdstr_table[9])
+/* "accept" */
+#define GRPC_MDSTR_ACCEPT (&grpc_static_mdstr_table[10])
+/* "accept-charset" */
+#define GRPC_MDSTR_ACCEPT_CHARSET (&grpc_static_mdstr_table[11])
+/* "accept-encoding" */
+#define GRPC_MDSTR_ACCEPT_ENCODING (&grpc_static_mdstr_table[12])
+/* "accept-language" */
+#define GRPC_MDSTR_ACCEPT_LANGUAGE (&grpc_static_mdstr_table[13])
+/* "accept-ranges" */
+#define GRPC_MDSTR_ACCEPT_RANGES (&grpc_static_mdstr_table[14])
+/* "access-control-allow-origin" */
+#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (&grpc_static_mdstr_table[15])
+/* "age" */
+#define GRPC_MDSTR_AGE (&grpc_static_mdstr_table[16])
+/* "allow" */
+#define GRPC_MDSTR_ALLOW (&grpc_static_mdstr_table[17])
+/* "application/grpc" */
+#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (&grpc_static_mdstr_table[18])
+/* ":authority" */
+#define GRPC_MDSTR_AUTHORITY (&grpc_static_mdstr_table[19])
+/* "authorization" */
+#define GRPC_MDSTR_AUTHORIZATION (&grpc_static_mdstr_table[20])
+/* "cache-control" */
+#define GRPC_MDSTR_CACHE_CONTROL (&grpc_static_mdstr_table[21])
+/* "content-disposition" */
+#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[22])
+/* "content-encoding" */
+#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[23])
+/* "content-language" */
+#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[24])
+/* "content-length" */
+#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[25])
+/* "content-location" */
+#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[26])
+/* "content-range" */
+#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[27])
+/* "content-type" */
+#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[28])
+/* "cookie" */
+#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[29])
+/* "date" */
+#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[30])
+/* "deflate" */
+#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[31])
+/* "deflate,gzip" */
+#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (&grpc_static_mdstr_table[32])
+/* "" */
+#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[33])
+/* "etag" */
+#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[34])
+/* "expect" */
+#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[35])
+/* "expires" */
+#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[36])
+/* "from" */
+#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[37])
+/* "GET" */
+#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[38])
+/* "grpc" */
+#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[39])
+/* "grpc-accept-encoding" */
+#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[40])
+/* "grpc-encoding" */
+#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[41])
+/* "grpc-internal-encoding-request" */
+#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[42])
+/* "grpc-message" */
+#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[43])
+/* "grpc-status" */
+#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[44])
+/* "grpc-timeout" */
+#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[45])
+/* "gzip" */
+#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[46])
+/* "gzip, deflate" */
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[47])
+/* "host" */
+#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[48])
+/* "http" */
+#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[49])
+/* "https" */
+#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[50])
+/* "identity" */
+#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[51])
+/* "identity,deflate" */
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[52])
+/* "identity,deflate,gzip" */
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
+ (&grpc_static_mdstr_table[53])
+/* "identity,gzip" */
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[54])
+/* "if-match" */
+#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[55])
+/* "if-modified-since" */
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[56])
+/* "if-none-match" */
+#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[57])
+/* "if-range" */
+#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[58])
+/* "if-unmodified-since" */
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[59])
+/* "last-modified" */
+#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[60])
+/* "link" */
+#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[61])
+/* "location" */
+#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[62])
+/* "max-forwards" */
+#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[63])
+/* ":method" */
+#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[64])
+/* ":path" */
+#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[65])
+/* "POST" */
+#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[66])
+/* "proxy-authenticate" */
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[67])
+/* "proxy-authorization" */
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[68])
+/* "range" */
+#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[69])
+/* "referer" */
+#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[70])
+/* "refresh" */
+#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[71])
+/* "retry-after" */
+#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[72])
+/* ":scheme" */
+#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[73])
+/* "server" */
+#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[74])
+/* "set-cookie" */
+#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[75])
+/* "/" */
+#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[76])
+/* "/index.html" */
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[77])
+/* ":status" */
+#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[78])
+/* "strict-transport-security" */
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[79])
+/* "te" */
+#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[80])
+/* "trailers" */
+#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[81])
+/* "transfer-encoding" */
+#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[82])
+/* "user-agent" */
+#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[83])
+/* "vary" */
+#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[84])
+/* "via" */
+#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[85])
+/* "www-authenticate" */
+#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[86])
+
+#define GRPC_STATIC_MDELEM_COUNT 78
+extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
+extern gpr_uintptr grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
+/* "accept-charset": "" */
+#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (&grpc_static_mdelem_table[0])
+/* "accept": "" */
+#define GRPC_MDELEM_ACCEPT_EMPTY (&grpc_static_mdelem_table[1])
+/* "accept-encoding": "" */
+#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY (&grpc_static_mdelem_table[2])
+/* "accept-encoding": "gzip, deflate" */
+#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \
+ (&grpc_static_mdelem_table[3])
+/* "accept-language": "" */
+#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY (&grpc_static_mdelem_table[4])
+/* "accept-ranges": "" */
+#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY (&grpc_static_mdelem_table[5])
+/* "access-control-allow-origin": "" */
+#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \
+ (&grpc_static_mdelem_table[6])
+/* "age": "" */
+#define GRPC_MDELEM_AGE_EMPTY (&grpc_static_mdelem_table[7])
+/* "allow": "" */
+#define GRPC_MDELEM_ALLOW_EMPTY (&grpc_static_mdelem_table[8])
+/* ":authority": "" */
+#define GRPC_MDELEM_AUTHORITY_EMPTY (&grpc_static_mdelem_table[9])
+/* "authorization": "" */
+#define GRPC_MDELEM_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[10])
+/* "cache-control": "" */
+#define GRPC_MDELEM_CACHE_CONTROL_EMPTY (&grpc_static_mdelem_table[11])
+/* "content-disposition": "" */
+#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY (&grpc_static_mdelem_table[12])
+/* "content-encoding": "" */
+#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY (&grpc_static_mdelem_table[13])
+/* "content-language": "" */
+#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY (&grpc_static_mdelem_table[14])
+/* "content-length": "" */
+#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY (&grpc_static_mdelem_table[15])
+/* "content-location": "" */
+#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (&grpc_static_mdelem_table[16])
+/* "content-range": "" */
+#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (&grpc_static_mdelem_table[17])
+/* "content-type": "application/grpc" */
+#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \
+ (&grpc_static_mdelem_table[18])
+/* "content-type": "" */
+#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (&grpc_static_mdelem_table[19])
+/* "cookie": "" */
+#define GRPC_MDELEM_COOKIE_EMPTY (&grpc_static_mdelem_table[20])
+/* "date": "" */
+#define GRPC_MDELEM_DATE_EMPTY (&grpc_static_mdelem_table[21])
+/* "etag": "" */
+#define GRPC_MDELEM_ETAG_EMPTY (&grpc_static_mdelem_table[22])
+/* "expect": "" */
+#define GRPC_MDELEM_EXPECT_EMPTY (&grpc_static_mdelem_table[23])
+/* "expires": "" */
+#define GRPC_MDELEM_EXPIRES_EMPTY (&grpc_static_mdelem_table[24])
+/* "from": "" */
+#define GRPC_MDELEM_FROM_EMPTY (&grpc_static_mdelem_table[25])
+/* "grpc-accept-encoding": "deflate" */
+#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE (&grpc_static_mdelem_table[26])
+/* "grpc-accept-encoding": "deflate,gzip" */
+#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \
+ (&grpc_static_mdelem_table[27])
+/* "grpc-accept-encoding": "gzip" */
+#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP (&grpc_static_mdelem_table[28])
+/* "grpc-accept-encoding": "identity" */
+#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \
+ (&grpc_static_mdelem_table[29])
+/* "grpc-accept-encoding": "identity,deflate" */
+#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \
+ (&grpc_static_mdelem_table[30])
+/* "grpc-accept-encoding": "identity,deflate,gzip" */
+#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
+ (&grpc_static_mdelem_table[31])
+/* "grpc-accept-encoding": "identity,gzip" */
+#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \
+ (&grpc_static_mdelem_table[32])
+/* "grpc-encoding": "deflate" */
+#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (&grpc_static_mdelem_table[33])
+/* "grpc-encoding": "gzip" */
+#define GRPC_MDELEM_GRPC_ENCODING_GZIP (&grpc_static_mdelem_table[34])
+/* "grpc-encoding": "identity" */
+#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (&grpc_static_mdelem_table[35])
+/* "grpc-status": "0" */
+#define GRPC_MDELEM_GRPC_STATUS_0 (&grpc_static_mdelem_table[36])
+/* "grpc-status": "1" */
+#define GRPC_MDELEM_GRPC_STATUS_1 (&grpc_static_mdelem_table[37])
+/* "grpc-status": "2" */
+#define GRPC_MDELEM_GRPC_STATUS_2 (&grpc_static_mdelem_table[38])
+/* "host": "" */
+#define GRPC_MDELEM_HOST_EMPTY (&grpc_static_mdelem_table[39])
+/* "if-match": "" */
+#define GRPC_MDELEM_IF_MATCH_EMPTY (&grpc_static_mdelem_table[40])
+/* "if-modified-since": "" */
+#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[41])
+/* "if-none-match": "" */
+#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (&grpc_static_mdelem_table[42])
+/* "if-range": "" */
+#define GRPC_MDELEM_IF_RANGE_EMPTY (&grpc_static_mdelem_table[43])
+/* "if-unmodified-since": "" */
+#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[44])
+/* "last-modified": "" */
+#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[45])
+/* "link": "" */
+#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[46])
+/* "location": "" */
+#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[47])
+/* "max-forwards": "" */
+#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[48])
+/* ":method": "GET" */
+#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[49])
+/* ":method": "POST" */
+#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[50])
+/* ":path": "/" */
+#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[51])
+/* ":path": "/index.html" */
+#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[52])
+/* "proxy-authenticate": "" */
+#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[53])
+/* "proxy-authorization": "" */
+#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[54])
+/* "range": "" */
+#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[55])
+/* "referer": "" */
+#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[56])
+/* "refresh": "" */
+#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[57])
+/* "retry-after": "" */
+#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[58])
+/* ":scheme": "grpc" */
+#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[59])
+/* ":scheme": "http" */
+#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[60])
+/* ":scheme": "https" */
+#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[61])
+/* "server": "" */
+#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[62])
+/* "set-cookie": "" */
+#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[63])
+/* ":status": "200" */
+#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[64])
+/* ":status": "204" */
+#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[65])
+/* ":status": "206" */
+#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[66])
+/* ":status": "304" */
+#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[67])
+/* ":status": "400" */
+#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[68])
+/* ":status": "404" */
+#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[69])
+/* ":status": "500" */
+#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[70])
+/* "strict-transport-security": "" */
+#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \
+ (&grpc_static_mdelem_table[71])
+/* "te": "trailers" */
+#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[72])
+/* "transfer-encoding": "" */
+#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[73])
+/* "user-agent": "" */
+#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[74])
+/* "vary": "" */
+#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[75])
+/* "via": "" */
+#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[76])
+/* "www-authenticate": "" */
+#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[77])
+
+extern const gpr_uint8
+ grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2];
+extern const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT];
+extern const gpr_uint8 grpc_static_accept_encoding_metadata[8];
+#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \
+ (&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]])
+#endif /* GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H */
diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb
index 7972272e2d..db9385e961 100644
--- a/src/ruby/ext/grpc/extconf.rb
+++ b/src/ruby/ext/grpc/extconf.rb
@@ -94,6 +94,10 @@ else
end
$CFLAGS << ' -I' + File.join(grpc_root, 'include')
$LDFLAGS << ' -L' + grpc_lib_dir
+ if grpc_config == 'gcov'
+ $CFLAGS << ' -O0 -fprofile-arcs -ftest-coverage'
+ $LDFLAGS << ' -fprofile-arcs -ftest-coverage -rdynamic'
+ end
raise 'gpr not found' unless have_library('gpr', 'gpr_now')
raise 'grpc not found' unless have_library('grpc', 'grpc_channel_destroy')
end
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index ed46e7b009..e1a4b8ed90 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -64,14 +64,13 @@ static void done_write(grpc_exec_ctx *exec_ctx, void *arg, int success) {
gpr_event_set(&a->done_write, (void *)1);
}
-static void server_setup_transport(void *ts, grpc_transport *transport,
- grpc_mdctx *mdctx) {
+static void server_setup_transport(void *ts, grpc_transport *transport) {
thd_args *a = ts;
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_server_setup_transport(&exec_ctx, a->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
+ GPR_ARRAY_SIZE(extra_filters),
grpc_server_get_channel_args(a->server));
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -84,7 +83,6 @@ void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator,
gpr_thd_id id;
char *hex;
grpc_transport *transport;
- grpc_mdctx *mdctx = grpc_mdctx_create();
gpr_slice slice =
gpr_slice_from_copied_buffer(client_payload, client_payload_length);
gpr_slice_buffer outgoing;
@@ -113,9 +111,8 @@ void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator,
a.validator = validator;
grpc_server_register_completion_queue(a.server, a.cq, NULL);
grpc_server_start(a.server);
- transport =
- grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, mdctx, 0);
- server_setup_transport(&a, transport, mdctx);
+ transport = grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, 0);
+ server_setup_transport(&a, transport);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 5e1ba11857..9dbb879300 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -93,13 +93,10 @@ static void test_create_channel_stack(void) {
grpc_call_element *call_elem;
grpc_arg arg;
grpc_channel_args chan_args;
- grpc_mdctx *metadata_context;
int *channel_data;
int *call_data;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- metadata_context = grpc_mdctx_create();
-
arg.type = GRPC_ARG_INTEGER;
arg.key = "test_key";
arg.value.integer = 42;
@@ -109,7 +106,7 @@ static void test_create_channel_stack(void) {
channel_stack = gpr_malloc(grpc_channel_stack_size(&filters, 1));
grpc_channel_stack_init(&exec_ctx, &filters, 1, NULL, &chan_args,
- metadata_context, channel_stack);
+ channel_stack);
GPR_ASSERT(channel_stack->count == 1);
channel_elem = grpc_channel_stack_element(channel_stack, 0);
channel_data = (int *)channel_elem->channel_data;
@@ -133,13 +130,13 @@ static void test_create_channel_stack(void) {
grpc_channel_stack_destroy(&exec_ctx, channel_stack);
gpr_free(channel_stack);
- grpc_mdctx_unref(metadata_context);
-
grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
+ grpc_init();
test_create_channel_stack();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/compression/compression_test.c b/test/core/compression/compression_test.c
index 633fbd97f4..35fadc00c0 100644
--- a/test/core/compression/compression_test.c
+++ b/test/core/compression/compression_test.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <grpc/compression.h>
+#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
@@ -71,7 +72,9 @@ static void test_compression_algorithm_parse(void) {
}
int main(int argc, char **argv) {
+ grpc_init();
test_compression_algorithm_parse();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/compression/message_compress_test.c b/test/core/compression/message_compress_test.c
index 98da6a1eaa..dfaed8484e 100644
--- a/test/core/compression/message_compress_test.c
+++ b/test/core/compression/message_compress_test.c
@@ -36,10 +36,12 @@
#include <stdlib.h>
#include <string.h>
-#include "test/core/util/test_config.h"
-#include "src/core/support/murmur_hash.h"
+#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
+
+#include "test/core/util/test_config.h"
+#include "src/core/support/murmur_hash.h"
#include "test/core/util/slice_splitter.h"
typedef enum { ONE_A = 0, ONE_KB_A, ONE_MB_A, TEST_VALUE_COUNT } test_value;
@@ -175,6 +177,7 @@ int main(int argc, char **argv) {
GRPC_SLICE_SPLIT_ONE_BYTE};
grpc_test_init(argc, argv);
+ grpc_init();
for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
for (j = 0; j < GPR_ARRAY_SIZE(uncompressed_split_modes); j++) {
@@ -189,6 +192,7 @@ int main(int argc, char **argv) {
}
test_bad_data();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c
index 1f5051f0ab..ccc8631d94 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.c
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.c
@@ -57,14 +57,13 @@
/* chttp2 transport that is immediately available (used for testing
connected_channel without a client_channel */
-static void server_setup_transport(void *ts, grpc_transport *transport,
- grpc_mdctx *mdctx) {
+static void server_setup_transport(void *ts, grpc_transport *transport) {
grpc_end2end_test_fixture *f = ts;
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_server_setup_transport(&exec_ctx, f->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
+ GPR_ARRAY_SIZE(extra_filters),
grpc_server_get_channel_args(f->server));
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -75,17 +74,15 @@ typedef struct {
} sp_client_setup;
static void client_setup_transport(grpc_exec_ctx *exec_ctx, void *ts,
- grpc_transport *transport,
- grpc_mdctx *mdctx) {
+ grpc_transport *transport) {
sp_client_setup *cs = ts;
const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
&grpc_compress_filter,
&grpc_connected_channel_filter};
size_t nfilters = sizeof(filters) / sizeof(*filters);
- grpc_channel *channel =
- grpc_channel_create_from_filters(exec_ctx, "socketpair-target", filters,
- nfilters, cs->client_args, mdctx, 1);
+ grpc_channel *channel = grpc_channel_create_from_filters(
+ exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);
cs->f->client = channel;
@@ -112,13 +109,12 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f,
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
grpc_transport *transport;
- grpc_mdctx *mdctx = grpc_mdctx_create();
sp_client_setup cs;
cs.client_args = client_args;
cs.f = f;
- transport = grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client,
- mdctx, 1);
- client_setup_transport(&exec_ctx, &cs, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1);
+ client_setup_transport(&exec_ctx, &cs, transport);
GPR_ASSERT(f->client);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
@@ -128,15 +124,14 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_transport *transport;
GPR_ASSERT(!f->server);
f->server = grpc_server_create_from_filters(NULL, 0, server_args);
grpc_server_register_completion_queue(f->server, f->cq, NULL);
grpc_server_start(f->server);
- transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server,
- mdctx, 0);
- server_setup_transport(f, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0);
+ server_setup_transport(f, transport);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
}
diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c
index b61fe98610..a6a84c9b1a 100644
--- a/test/core/end2end/fixtures/h2_sockpair.c
+++ b/test/core/end2end/fixtures/h2_sockpair.c
@@ -56,14 +56,13 @@
/* chttp2 transport that is immediately available (used for testing
connected_channel without a client_channel */
-static void server_setup_transport(void *ts, grpc_transport *transport,
- grpc_mdctx *mdctx) {
+static void server_setup_transport(void *ts, grpc_transport *transport) {
grpc_end2end_test_fixture *f = ts;
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_server_setup_transport(&exec_ctx, f->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
+ GPR_ARRAY_SIZE(extra_filters),
grpc_server_get_channel_args(f->server));
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -74,17 +73,15 @@ typedef struct {
} sp_client_setup;
static void client_setup_transport(grpc_exec_ctx *exec_ctx, void *ts,
- grpc_transport *transport,
- grpc_mdctx *mdctx) {
+ grpc_transport *transport) {
sp_client_setup *cs = ts;
const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
&grpc_compress_filter,
&grpc_connected_channel_filter};
size_t nfilters = sizeof(filters) / sizeof(*filters);
- grpc_channel *channel =
- grpc_channel_create_from_filters(exec_ctx, "socketpair-target", filters,
- nfilters, cs->client_args, mdctx, 1);
+ grpc_channel *channel = grpc_channel_create_from_filters(
+ exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);
cs->f->client = channel;
@@ -111,13 +108,12 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f,
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
grpc_transport *transport;
- grpc_mdctx *mdctx = grpc_mdctx_create();
sp_client_setup cs;
cs.client_args = client_args;
cs.f = f;
- transport = grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client,
- mdctx, 1);
- client_setup_transport(&exec_ctx, &cs, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1);
+ client_setup_transport(&exec_ctx, &cs, transport);
GPR_ASSERT(f->client);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
@@ -127,15 +123,14 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_transport *transport;
GPR_ASSERT(!f->server);
f->server = grpc_server_create_from_filters(NULL, 0, server_args);
grpc_server_register_completion_queue(f->server, f->cq, NULL);
grpc_server_start(f->server);
- transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server,
- mdctx, 0);
- server_setup_transport(f, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0);
+ server_setup_transport(f, transport);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
}
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c
index 9f0fd2ea9a..4b8f9054ef 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.c
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c
@@ -56,14 +56,13 @@
/* chttp2 transport that is immediately available (used for testing
connected_channel without a client_channel */
-static void server_setup_transport(void *ts, grpc_transport *transport,
- grpc_mdctx *mdctx) {
+static void server_setup_transport(void *ts, grpc_transport *transport) {
grpc_end2end_test_fixture *f = ts;
static grpc_channel_filter const *extra_filters[] = {
&grpc_http_server_filter};
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_server_setup_transport(&exec_ctx, f->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
+ GPR_ARRAY_SIZE(extra_filters),
grpc_server_get_channel_args(f->server));
grpc_exec_ctx_finish(&exec_ctx);
}
@@ -74,17 +73,15 @@ typedef struct {
} sp_client_setup;
static void client_setup_transport(grpc_exec_ctx *exec_ctx, void *ts,
- grpc_transport *transport,
- grpc_mdctx *mdctx) {
+ grpc_transport *transport) {
sp_client_setup *cs = ts;
const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
&grpc_compress_filter,
&grpc_connected_channel_filter};
size_t nfilters = sizeof(filters) / sizeof(*filters);
- grpc_channel *channel =
- grpc_channel_create_from_filters(exec_ctx, "socketpair-target", filters,
- nfilters, cs->client_args, mdctx, 1);
+ grpc_channel *channel = grpc_channel_create_from_filters(
+ exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);
cs->f->client = channel;
@@ -111,13 +108,12 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f,
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
grpc_transport *transport;
- grpc_mdctx *mdctx = grpc_mdctx_create();
sp_client_setup cs;
cs.client_args = client_args;
cs.f = f;
- transport = grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client,
- mdctx, 1);
- client_setup_transport(&exec_ctx, &cs, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1);
+ client_setup_transport(&exec_ctx, &cs, transport);
GPR_ASSERT(f->client);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
@@ -127,15 +123,14 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_endpoint_pair *sfd = f->fixture_data;
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_transport *transport;
GPR_ASSERT(!f->server);
f->server = grpc_server_create_from_filters(NULL, 0, server_args);
grpc_server_register_completion_queue(f->server, f->cq, NULL);
grpc_server_start(f->server);
- transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server,
- mdctx, 0);
- server_setup_transport(f, transport, mdctx);
+ transport =
+ grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0);
+ server_setup_transport(f, transport);
grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
grpc_exec_ctx_finish(&exec_ctx);
}
diff --git a/test/core/end2end/fixtures/h2_uchannel.c b/test/core/end2end/fixtures/h2_uchannel.c
index d1f9d38b82..ee4a60c29a 100644
--- a/test/core/end2end/fixtures/h2_uchannel.c
+++ b/test/core/end2end/fixtures/h2_uchannel.c
@@ -66,8 +66,6 @@ typedef struct {
grpc_endpoint *tcp;
- grpc_mdctx *mdctx;
-
grpc_closure connected;
} connector;
@@ -79,7 +77,6 @@ static void connector_ref(grpc_connector *con) {
static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
connector *c = (connector *)con;
if (gpr_unref(&c->refs)) {
- grpc_mdctx_unref(c->mdctx);
gpr_free(c);
}
}
@@ -89,8 +86,8 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, int success) {
grpc_closure *notify;
grpc_endpoint *tcp = c->tcp;
if (tcp != NULL) {
- c->result->transport = grpc_create_chttp2_transport(
- exec_ctx, c->args.channel_args, tcp, c->mdctx, 1);
+ c->result->transport =
+ grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1);
grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
0);
GPR_ASSERT(c->result->transport);
@@ -130,7 +127,6 @@ static const grpc_connector_vtable connector_vtable = {
typedef struct {
grpc_subchannel_factory base;
gpr_refcount refs;
- grpc_mdctx *mdctx;
grpc_channel_args *merge_args;
grpc_channel *master;
grpc_subchannel **sniffed_subchannel;
@@ -147,7 +143,6 @@ static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
if (gpr_unref(&f->refs)) {
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
grpc_channel_args_destroy(f->merge_args);
- grpc_mdctx_unref(f->mdctx);
gpr_free(f);
}
}
@@ -162,10 +157,7 @@ static grpc_subchannel *subchannel_factory_create_subchannel(
grpc_subchannel *s;
memset(c, 0, sizeof(*c));
c->base.vtable = &connector_vtable;
- c->mdctx = f->mdctx;
- grpc_mdctx_ref(c->mdctx);
gpr_ref_init(&c->refs, 1);
- args->mdctx = f->mdctx;
args->args = final_args;
args->master = f->master;
s = grpc_subchannel_create(&c->base, args);
@@ -188,22 +180,19 @@ grpc_channel *channel_create(const char *target, const grpc_channel_args *args,
const grpc_channel_filter *filters[MAX_FILTERS];
grpc_resolver *resolver;
subchannel_factory *f;
- grpc_mdctx *mdctx = grpc_mdctx_create();
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
size_t n = 0;
filters[n++] = &grpc_client_channel_filter;
GPR_ASSERT(n <= MAX_FILTERS);
- channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
- args, mdctx, 1);
+ channel =
+ grpc_channel_create_from_filters(&exec_ctx, target, filters, n, args, 1);
f = gpr_malloc(sizeof(*f));
f->sniffed_subchannel = sniffed_subchannel;
f->base.vtable = &test_subchannel_factory_vtable;
gpr_ref_init(&f->refs, 1);
- grpc_mdctx_ref(mdctx);
- f->mdctx = mdctx;
f->merge_args = grpc_channel_args_copy(args);
f->master = channel;
GRPC_CHANNEL_INTERNAL_REF(f->master, "test_subchannel_factory");
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index f592f63ba9..4be6957a83 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -121,7 +121,7 @@ static void session_shutdown_cb(grpc_exec_ctx *exec_ctx, void *arg, /*session */
int success) {
session *se = arg;
server *sv = se->sv;
- grpc_fd_orphan(exec_ctx, se->em_fd, NULL, "a");
+ grpc_fd_orphan(exec_ctx, se->em_fd, NULL, NULL, "a");
gpr_free(se);
/* Start to shutdown listen fd. */
grpc_fd_shutdown(exec_ctx, sv->em_fd);
@@ -177,7 +177,7 @@ static void listen_shutdown_cb(grpc_exec_ctx *exec_ctx, void *arg /*server */,
int success) {
server *sv = arg;
- grpc_fd_orphan(exec_ctx, sv->em_fd, NULL, "b");
+ grpc_fd_orphan(exec_ctx, sv->em_fd, NULL, NULL, "b");
gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
sv->done = 1;
@@ -294,7 +294,7 @@ static void client_init(client *cl) {
static void client_session_shutdown_cb(grpc_exec_ctx *exec_ctx,
void *arg /*client */, int success) {
client *cl = arg;
- grpc_fd_orphan(exec_ctx, cl->em_fd, NULL, "c");
+ grpc_fd_orphan(exec_ctx, cl->em_fd, NULL, NULL, "c");
cl->done = 1;
grpc_pollset_kick(&g_pollset, NULL);
}
@@ -503,7 +503,7 @@ static void test_grpc_fd_change(void) {
GPR_ASSERT(b.cb_that_ran == second_read_callback);
gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
- grpc_fd_orphan(&exec_ctx, em_fd, NULL, "d");
+ grpc_fd_orphan(&exec_ctx, em_fd, NULL, NULL, "d");
grpc_exec_ctx_finish(&exec_ctx);
destroy_change_data(&a);
destroy_change_data(&b);
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index f676454b7f..9feac931a3 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -383,6 +383,76 @@ static void write_test(size_t num_bytes, size_t slice_size) {
grpc_exec_ctx_finish(&exec_ctx);
}
+void on_fd_released(grpc_exec_ctx *exec_ctx, void *arg, int success) {
+ int *done = arg;
+ *done = 1;
+ grpc_pollset_kick(&g_pollset, NULL);
+}
+
+/* Do a read_test, then release fd and try to read/write again. */
+static void release_fd_test(size_t num_bytes, size_t slice_size) {
+ int sv[2];
+ grpc_endpoint *ep;
+ struct read_socket_state state;
+ size_t written_bytes;
+ int fd;
+ gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_closure fd_released_cb;
+ int fd_released_done = 0;
+ grpc_closure_init(&fd_released_cb, &on_fd_released, &fd_released_done);
+
+ gpr_log(GPR_INFO, "Release fd read_test of size %d, slice size %d", num_bytes,
+ slice_size);
+
+ create_sockets(sv);
+
+ ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), slice_size, "test");
+ grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+
+ written_bytes = fill_socket_partial(sv[0], num_bytes);
+ gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
+
+ state.ep = ep;
+ state.read_bytes = 0;
+ state.target_read_bytes = written_bytes;
+ gpr_slice_buffer_init(&state.incoming);
+ grpc_closure_init(&state.read_cb, read_cb, &state);
+
+ grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
+
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ while (state.read_bytes < state.target_read_bytes) {
+ grpc_pollset_worker worker;
+ grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ gpr_now(GPR_CLOCK_MONOTONIC), deadline);
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ grpc_exec_ctx_finish(&exec_ctx);
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ }
+ GPR_ASSERT(state.read_bytes == state.target_read_bytes);
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+
+ gpr_slice_buffer_destroy(&state.incoming);
+ grpc_tcp_destroy_and_release_fd(&exec_ctx, ep, &fd, &fd_released_cb);
+ gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+ while (!fd_released_done) {
+ grpc_pollset_worker worker;
+ grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+ gpr_now(GPR_CLOCK_MONOTONIC), deadline);
+ }
+ gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+ GPR_ASSERT(fd_released_done == 1);
+ GPR_ASSERT(fd == sv[1]);
+ grpc_exec_ctx_finish(&exec_ctx);
+
+ written_bytes = fill_socket_partial(sv[0], num_bytes);
+ drain_socket_blocking(fd, written_bytes, written_bytes);
+ written_bytes = fill_socket_partial(fd, num_bytes);
+ drain_socket_blocking(sv[0], written_bytes, written_bytes);
+ close(fd);
+}
+
void run_tests(void) {
size_t i = 0;
@@ -402,6 +472,8 @@ void run_tests(void) {
for (i = 1; i < 1000; i = GPR_MAX(i + 1, i * 5 / 4)) {
write_test(40320, i);
}
+
+ release_fd_test(100, 8192);
}
static void clean_up(void) {}
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index 6553e0da20..64ea1e3f14 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -46,7 +46,6 @@
#define TEST(x) run_test(x, #x)
-grpc_mdctx *g_mdctx;
grpc_chttp2_hpack_compressor g_compressor;
int g_failure = 0;
@@ -76,7 +75,7 @@ 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(g_mdctx, key, value);
+ e[i].md = grpc_mdelem_from_strings(key, value);
}
e[0].prev = NULL;
e[nheaders - 1].next = NULL;
@@ -181,18 +180,18 @@ static void test_decode_table_overflow(void) {
static void run_test(void (*test)(), const char *name) {
gpr_log(GPR_INFO, "RUN TEST: %s", name);
- g_mdctx = grpc_mdctx_create_with_seed(0);
- grpc_chttp2_hpack_compressor_init(&g_compressor, g_mdctx);
+ grpc_chttp2_hpack_compressor_init(&g_compressor);
test();
grpc_chttp2_hpack_compressor_destroy(&g_compressor);
- grpc_mdctx_unref(g_mdctx);
}
int main(int argc, char **argv) {
size_t i;
grpc_test_init(argc, argv);
+ grpc_init();
TEST(test_basic_headers);
TEST(test_decode_table_overflow);
+ grpc_shutdown();
for (i = 0; i < num_to_delete; i++) {
gpr_free(to_delete[i]);
}
diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c
index c6b35fba79..4456e197af 100644
--- a/test/core/transport/chttp2/hpack_parser_test.c
+++ b/test/core/transport/chttp2/hpack_parser_test.c
@@ -35,6 +35,7 @@
#include <stdarg.h>
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/slice.h>
@@ -90,9 +91,8 @@ static void test_vector(grpc_chttp2_hpack_parser *parser,
static void test_vectors(grpc_slice_split_mode mode) {
grpc_chttp2_hpack_parser parser;
- grpc_mdctx *mdctx = grpc_mdctx_create();
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ grpc_chttp2_hpack_parser_init(&parser);
/* D.2.1 */
test_vector(&parser, mode,
"400a 6375 7374 6f6d 2d6b 6579 0d63 7573"
@@ -110,7 +110,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
test_vector(&parser, mode, "82", ":method", "GET", NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ grpc_chttp2_hpack_parser_init(&parser);
/* D.3.1 */
test_vector(&parser, mode,
"8286 8441 0f77 7777 2e65 7861 6d70 6c65"
@@ -130,7 +130,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ grpc_chttp2_hpack_parser_init(&parser);
/* D.4.1 */
test_vector(&parser, mode,
"8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4"
@@ -150,7 +150,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ 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);
/* D.5.1 */
@@ -184,7 +184,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_chttp2_hpack_parser_init(&parser, mdctx);
+ 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);
/* D.6.1 */
@@ -214,12 +214,13 @@ static void test_vectors(grpc_slice_split_mode mode) {
"set-cookie",
"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", NULL);
grpc_chttp2_hpack_parser_destroy(&parser);
- grpc_mdctx_unref(mdctx);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
+ grpc_init();
test_vectors(GRPC_SLICE_SPLIT_MERGE_ALL);
test_vectors(GRPC_SLICE_SPLIT_ONE_BYTE);
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c
index 5eb52d6d9a..50496a305d 100644
--- a/test/core/transport/chttp2/hpack_table_test.c
+++ b/test/core/transport/chttp2/hpack_table_test.c
@@ -36,10 +36,12 @@
#include <string.h>
#include <stdio.h>
-#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include <grpc/grpc.h>
+
+#include "src/core/support/string.h"
#include "test/core/util/test_config.h"
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
@@ -58,10 +60,8 @@ static void assert_index(const grpc_chttp2_hptbl *tbl, gpr_uint32 idx,
static void test_static_lookup(void) {
grpc_chttp2_hptbl tbl;
- grpc_mdctx *mdctx;
- mdctx = grpc_mdctx_create();
- grpc_chttp2_hptbl_init(&tbl, mdctx);
+ grpc_chttp2_hptbl_init(&tbl);
LOG_TEST("test_static_lookup");
assert_index(&tbl, 1, ":authority", "");
@@ -127,7 +127,6 @@ static void test_static_lookup(void) {
assert_index(&tbl, 61, "www-authenticate", "");
grpc_chttp2_hptbl_destroy(&tbl);
- grpc_mdctx_unref(mdctx);
}
static void test_many_additions(void) {
@@ -135,18 +134,16 @@ static void test_many_additions(void) {
int i;
char *key;
char *value;
- grpc_mdctx *mdctx;
LOG_TEST("test_many_additions");
- mdctx = grpc_mdctx_create();
- grpc_chttp2_hptbl_init(&tbl, mdctx);
+ grpc_chttp2_hptbl_init(&tbl);
for (i = 0; i < 1000000; i++) {
grpc_mdelem *elem;
gpr_asprintf(&key, "K:%d", i);
gpr_asprintf(&value, "VALUE:%d", i);
- elem = grpc_mdelem_from_strings(mdctx, key, value);
+ elem = grpc_mdelem_from_strings(key, value);
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
assert_index(&tbl, 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY, key, value);
@@ -162,13 +159,12 @@ static void test_many_additions(void) {
}
grpc_chttp2_hptbl_destroy(&tbl);
- grpc_mdctx_unref(mdctx);
}
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(tbl->mdctx, key, value);
+ grpc_mdelem *md = grpc_mdelem_from_strings(key, value);
grpc_chttp2_hptbl_find_result r = grpc_chttp2_hptbl_find(tbl, md);
GRPC_MDELEM_UNREF(md);
return r;
@@ -178,21 +174,19 @@ static void test_find(void) {
grpc_chttp2_hptbl tbl;
gpr_uint32 i;
char buffer[32];
- grpc_mdctx *mdctx;
grpc_mdelem *elem;
grpc_chttp2_hptbl_find_result r;
LOG_TEST("test_find");
- mdctx = grpc_mdctx_create();
- grpc_chttp2_hptbl_init(&tbl, mdctx);
- elem = grpc_mdelem_from_strings(mdctx, "abc", "xyz");
+ grpc_chttp2_hptbl_init(&tbl);
+ elem = grpc_mdelem_from_strings("abc", "xyz");
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
- elem = grpc_mdelem_from_strings(mdctx, "abc", "123");
+ elem = grpc_mdelem_from_strings("abc", "123");
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
- elem = grpc_mdelem_from_strings(mdctx, "x", "1");
+ elem = grpc_mdelem_from_strings("x", "1");
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
@@ -243,7 +237,7 @@ static void test_find(void) {
/* overflow the string buffer, check find still works */
for (i = 0; i < 10000; i++) {
gpr_ltoa(i, buffer);
- elem = grpc_mdelem_from_strings(mdctx, "test", buffer);
+ elem = grpc_mdelem_from_strings("test", buffer);
GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
GRPC_MDELEM_UNREF(elem);
}
@@ -274,13 +268,14 @@ static void test_find(void) {
GPR_ASSERT(r.has_value == 0);
grpc_chttp2_hptbl_destroy(&tbl);
- grpc_mdctx_unref(mdctx);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
+ grpc_init();
test_static_lookup();
test_many_additions();
test_find();
+ grpc_shutdown();
return 0;
}
diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c
index 080e86cb63..9c1eae9552 100644
--- a/test/core/transport/metadata_test.c
+++ b/test/core/transport/metadata_test.c
@@ -35,11 +35,13 @@
#include <stdio.h>
-#include "src/core/support/string.h"
-#include "src/core/transport/chttp2/bin_encoder.h"
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+
+#include "src/core/support/string.h"
+#include "src/core/transport/chttp2/bin_encoder.h"
#include "test/core/util/test_config.h"
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
@@ -48,44 +50,39 @@
#define MANY 10000
static void test_no_op(void) {
- grpc_mdctx *ctx;
-
LOG_TEST("test_no_op");
-
- ctx = grpc_mdctx_create();
- grpc_mdctx_unref(ctx);
+ grpc_init();
+ grpc_shutdown();
}
static void test_create_string(void) {
- grpc_mdctx *ctx;
grpc_mdstr *s1, *s2, *s3;
LOG_TEST("test_create_string");
- ctx = grpc_mdctx_create();
- s1 = grpc_mdstr_from_string(ctx, "hello");
- s2 = grpc_mdstr_from_string(ctx, "hello");
- s3 = grpc_mdstr_from_string(ctx, "very much not hello");
+ 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(gpr_slice_str_cmp(s1->slice, "hello") == 0);
GPR_ASSERT(gpr_slice_str_cmp(s3->slice, "very much not hello") == 0);
GRPC_MDSTR_UNREF(s1);
GRPC_MDSTR_UNREF(s2);
- grpc_mdctx_unref(ctx);
GRPC_MDSTR_UNREF(s3);
+ grpc_shutdown();
}
static void test_create_metadata(void) {
- grpc_mdctx *ctx;
grpc_mdelem *m1, *m2, *m3;
LOG_TEST("test_create_metadata");
- ctx = grpc_mdctx_create();
- m1 = grpc_mdelem_from_strings(ctx, "a", "b");
- m2 = grpc_mdelem_from_strings(ctx, "a", "b");
- m3 = grpc_mdelem_from_strings(ctx, "a", "c");
+ 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);
@@ -96,32 +93,25 @@ static void test_create_metadata(void) {
GRPC_MDELEM_UNREF(m1);
GRPC_MDELEM_UNREF(m2);
GRPC_MDELEM_UNREF(m3);
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
}
static void test_create_many_ephemeral_metadata(void) {
- grpc_mdctx *ctx;
char buffer[GPR_LTOA_MIN_BUFSIZE];
long i;
- size_t mdtab_capacity_before;
LOG_TEST("test_create_many_ephemeral_metadata");
- ctx = grpc_mdctx_create();
- mdtab_capacity_before = grpc_mdctx_get_mdtab_capacity_test_only(ctx);
+ grpc_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(ctx, "a", buffer));
+ GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", buffer));
}
- /* capacity should not grow */
- GPR_ASSERT(mdtab_capacity_before ==
- grpc_mdctx_get_mdtab_capacity_test_only(ctx));
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
}
static void test_create_many_persistant_metadata(void) {
- grpc_mdctx *ctx;
char buffer[GPR_LTOA_MIN_BUFSIZE];
long i;
grpc_mdelem **created = gpr_malloc(sizeof(grpc_mdelem *) * MANY);
@@ -129,16 +119,16 @@ static void test_create_many_persistant_metadata(void) {
LOG_TEST("test_create_many_persistant_metadata");
- ctx = grpc_mdctx_create();
+ grpc_init();
/* add phase */
for (i = 0; i < MANY; i++) {
gpr_ltoa(i, buffer);
- created[i] = grpc_mdelem_from_strings(ctx, "a", buffer);
+ created[i] = grpc_mdelem_from_strings("a", buffer);
}
/* verify phase */
for (i = 0; i < MANY; i++) {
gpr_ltoa(i, buffer);
- md = grpc_mdelem_from_strings(ctx, "a", buffer);
+ md = grpc_mdelem_from_strings("a", buffer);
GPR_ASSERT(md == created[i]);
GRPC_MDELEM_UNREF(md);
}
@@ -146,37 +136,22 @@ static void test_create_many_persistant_metadata(void) {
for (i = 0; i < MANY; i++) {
GRPC_MDELEM_UNREF(created[i]);
}
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
gpr_free(created);
}
static void test_spin_creating_the_same_thing(void) {
- grpc_mdctx *ctx;
-
LOG_TEST("test_spin_creating_the_same_thing");
- ctx = grpc_mdctx_create();
- GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 0);
- GPR_ASSERT(grpc_mdctx_get_mdtab_free_test_only(ctx) == 0);
-
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings(ctx, "a", "b"));
- GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 1);
- GPR_ASSERT(grpc_mdctx_get_mdtab_free_test_only(ctx) == 1);
-
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings(ctx, "a", "b"));
- GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 1);
- GPR_ASSERT(grpc_mdctx_get_mdtab_free_test_only(ctx) == 1);
-
- GRPC_MDELEM_UNREF(grpc_mdelem_from_strings(ctx, "a", "b"));
- GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 1);
- GPR_ASSERT(grpc_mdctx_get_mdtab_free_test_only(ctx) == 1);
-
- grpc_mdctx_unref(ctx);
+ 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_shutdown();
}
static void test_things_stick_around(void) {
- grpc_mdctx *ctx;
size_t i, j;
char *buffer;
size_t nstrs = 1000;
@@ -186,11 +161,11 @@ static void test_things_stick_around(void) {
LOG_TEST("test_things_stick_around");
- ctx = grpc_mdctx_create();
+ grpc_init();
for (i = 0; i < nstrs; i++) {
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", i);
- strs[i] = grpc_mdstr_from_string(ctx, buffer);
+ strs[i] = grpc_mdstr_from_string(buffer);
shuf[i] = i;
gpr_free(buffer);
}
@@ -212,60 +187,58 @@ static void test_things_stick_around(void) {
GRPC_MDSTR_UNREF(strs[shuf[i]]);
for (j = i + 1; j < nstrs; j++) {
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", shuf[j]);
- test = grpc_mdstr_from_string(ctx, buffer);
+ test = grpc_mdstr_from_string(buffer);
GPR_ASSERT(test == strs[shuf[j]]);
GRPC_MDSTR_UNREF(test);
gpr_free(buffer);
}
}
- grpc_mdctx_unref(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_mdctx *ctx;
grpc_mdstr *str;
gpr_slice slice;
LOG_TEST("test_slices_work");
- ctx = grpc_mdctx_create();
+ grpc_init();
str = grpc_mdstr_from_string(
- ctx, "123456789012345678901234567890123456789012345678901234567890");
+ "123456789012345678901234567890123456789012345678901234567890");
slice = gpr_slice_ref(str->slice);
GRPC_MDSTR_UNREF(str);
gpr_slice_unref(slice);
str = grpc_mdstr_from_string(
- ctx, "123456789012345678901234567890123456789012345678901234567890");
+ "123456789012345678901234567890123456789012345678901234567890");
slice = gpr_slice_ref(str->slice);
gpr_slice_unref(slice);
GRPC_MDSTR_UNREF(str);
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
}
static void test_base64_and_huffman_works(void) {
- grpc_mdctx *ctx;
grpc_mdstr *str;
gpr_slice slice1;
gpr_slice slice2;
LOG_TEST("test_base64_and_huffman_works");
- ctx = grpc_mdctx_create();
- str = grpc_mdstr_from_string(ctx, "abcdefg");
+ 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 == gpr_slice_cmp(slice1, slice2));
gpr_slice_unref(slice2);
GRPC_MDSTR_UNREF(str);
- grpc_mdctx_unref(ctx);
+ grpc_shutdown();
}
int main(int argc, char **argv) {
diff --git a/test/proto/metrics.proto b/test/proto/metrics.proto
index f5a08e056a..f698620100 100644
--- a/test/proto/metrics.proto
+++ b/test/proto/metrics.proto
@@ -43,9 +43,7 @@ message GaugeResponse {
}
}
-message GaugeRequest {
- string name = 1;
-}
+message GaugeRequest { string name = 1; }
message EmptyMessage {
}
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
new file mode 100755
index 0000000000..86cb4143f8
--- /dev/null
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -0,0 +1,310 @@
+#!/usr/bin/env python2.7
+
+# 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.
+
+import hashlib
+import itertools
+import os
+import sys
+
+# configuration: a list of either strings or 2-tuples of strings
+# a single string represents a static grpc_mdstr
+# a 2-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will
+# also be created)
+
+CONFIG = [
+ 'grpc-timeout',
+ 'grpc-internal-encoding-request',
+ ':path',
+ 'grpc-encoding',
+ 'grpc-accept-encoding',
+ 'user-agent',
+ ':authority',
+ 'host',
+ 'grpc-message',
+ 'grpc-status',
+ '',
+ ('grpc-status', '0'),
+ ('grpc-status', '1'),
+ ('grpc-status', '2'),
+ ('grpc-encoding', 'identity'),
+ ('grpc-encoding', 'gzip'),
+ ('grpc-encoding', 'deflate'),
+ ('te', 'trailers'),
+ ('content-type', 'application/grpc'),
+ (':method', 'POST'),
+ (':status', '200'),
+ (':status', '404'),
+ (':scheme', 'http'),
+ (':scheme', 'https'),
+ (':scheme', 'grpc'),
+ (':authority', ''),
+ (':method', 'GET'),
+ (':path', '/'),
+ (':path', '/index.html'),
+ (':status', '204'),
+ (':status', '206'),
+ (':status', '304'),
+ (':status', '400'),
+ (':status', '500'),
+ ('accept-charset', ''),
+ ('accept-encoding', ''),
+ ('accept-encoding', 'gzip, deflate'),
+ ('accept-language', ''),
+ ('accept-ranges', ''),
+ ('accept', ''),
+ ('access-control-allow-origin', ''),
+ ('age', ''),
+ ('allow', ''),
+ ('authorization', ''),
+ ('cache-control', ''),
+ ('content-disposition', ''),
+ ('content-encoding', ''),
+ ('content-language', ''),
+ ('content-length', ''),
+ ('content-location', ''),
+ ('content-range', ''),
+ ('content-type', ''),
+ ('cookie', ''),
+ ('date', ''),
+ ('etag', ''),
+ ('expect', ''),
+ ('expires', ''),
+ ('from', ''),
+ ('host', ''),
+ ('if-match', ''),
+ ('if-modified-since', ''),
+ ('if-none-match', ''),
+ ('if-range', ''),
+ ('if-unmodified-since', ''),
+ ('last-modified', ''),
+ ('link', ''),
+ ('location', ''),
+ ('max-forwards', ''),
+ ('proxy-authenticate', ''),
+ ('proxy-authorization', ''),
+ ('range', ''),
+ ('referer', ''),
+ ('refresh', ''),
+ ('retry-after', ''),
+ ('server', ''),
+ ('set-cookie', ''),
+ ('strict-transport-security', ''),
+ ('transfer-encoding', ''),
+ ('user-agent', ''),
+ ('vary', ''),
+ ('via', ''),
+ ('www-authenticate', ''),
+]
+
+COMPRESSION_ALGORITHMS = [
+ 'identity',
+ 'deflate',
+ 'gzip',
+]
+
+# utility: mangle the name of a config
+def mangle(elem):
+ xl = {
+ '-': '_',
+ ':': '',
+ '/': 'slash',
+ '.': 'dot',
+ ',': 'comma',
+ ' ': '_',
+ }
+ def m0(x):
+ if not x: return 'empty'
+ r = ''
+ for c in x:
+ put = xl.get(c, c.lower())
+ if not put: continue
+ last_is_underscore = r[-1] == '_' if r else True
+ if last_is_underscore and put == '_': continue
+ elif len(put) > 1:
+ if not last_is_underscore: r += '_'
+ r += put
+ r += '_'
+ else:
+ r += put
+ if r[-1] == '_': r = r[:-1]
+ return r
+ if isinstance(elem, tuple):
+ return 'grpc_mdelem_%s_%s' % (m0(elem[0]), m0(elem[1]))
+ else:
+ return 'grpc_mdstr_%s' % (m0(elem))
+
+# utility: generate some hash value for a string
+def fake_hash(elem):
+ return hashlib.md5(elem).hexdigest()[0:8]
+
+# utility: print a big comment block into a set of files
+def put_banner(files, banner):
+ for f in files:
+ print >>f, '/*'
+ for line in banner:
+ print >>f, ' * %s' % line
+ print >>f, ' */'
+ print >>f
+
+# build a list of all the strings we need
+all_strs = set()
+all_elems = set()
+static_userdata = {}
+for elem in CONFIG:
+ if isinstance(elem, tuple):
+ all_strs.add(elem[0])
+ all_strs.add(elem[1])
+ all_elems.add(elem)
+ else:
+ all_strs.add(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)
+ compression_elems.append(elem)
+ static_userdata[elem] = 1 + mask
+all_strs = sorted(list(all_strs), key=mangle)
+all_elems = sorted(list(all_elems), key=mangle)
+
+# output configuration
+args = sys.argv[1:]
+H = None
+C = None
+if args:
+ if 'header' in args:
+ H = sys.stdout
+ else:
+ H = open('/dev/null', 'w')
+ if 'source' in args:
+ C = sys.stdout
+ else:
+ C = open('/dev/null', 'w')
+else:
+ H = open(os.path.join(
+ os.path.dirname(sys.argv[0]), '../../../src/core/transport/static_metadata.h'), 'w')
+ C = open(os.path.join(
+ os.path.dirname(sys.argv[0]), '../../../src/core/transport/static_metadata.c'), 'w')
+
+# copy-paste copyright notice from this file
+with open(sys.argv[0]) as my_source:
+ copyright = []
+ for line in my_source:
+ if line[0] != '#': break
+ for line in my_source:
+ if line[0] == '#':
+ copyright.append(line)
+ break
+ for line in my_source:
+ if line[0] != '#':
+ break
+ copyright.append(line)
+ put_banner([H,C], [line[1:].strip() for line in copyright])
+
+put_banner([H,C],
+"""WARNING: Auto-generated code.
+
+To make changes to this file, change tools/codegen/core/gen_static_metadata.py,
+and then re-run it.
+
+See metadata.h for an explanation of the interface here, and metadata.c for an
+explanation of what's going on.
+""".splitlines())
+
+print >>H, '#ifndef GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H'
+print >>H, '#define GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H'
+print >>H
+print >>H, '#include "src/core/transport/metadata.h"'
+print >>H
+
+print >>C, '#include "src/core/transport/static_metadata.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];'
+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
+print >>C, 'grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];'
+print >>C
+
+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 gpr_uintptr 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
+print >>C, 'grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];'
+print >>C, 'gpr_uintptr 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, '};'
+print >>C
+
+def str_idx(s):
+ for i, s2 in enumerate(all_strs):
+ if s == s2:
+ return i
+
+def md_idx(m):
+ for i, m2 in enumerate(all_elems):
+ if m == m2:
+ return i
+
+print >>H, 'extern const gpr_uint8 grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT*2];'
+print >>C, 'const gpr_uint8 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, '};'
+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 >>C
+
+print >>H, 'extern const gpr_uint8 grpc_static_accept_encoding_metadata[%d];' % (1 << len(COMPRESSION_ALGORITHMS))
+print >>C, 'const gpr_uint8 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, '#endif /* GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H */'
+
+H.close()
+C.close()
+
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index cf1563be60..8dcd8cd42c 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -810,6 +810,7 @@ src/core/client_config/subchannel_factory.h \
src/core/client_config/subchannel_factory_decorators/add_channel_arg.h \
src/core/client_config/subchannel_factory_decorators/merge_channel_args.h \
src/core/client_config/uri_parser.h \
+src/core/compression/algorithm_metadata.h \
src/core/compression/message_compress.h \
src/core/debug/trace.h \
src/core/httpcli/format_request.h \
@@ -892,6 +893,7 @@ src/core/transport/chttp2_transport.h \
src/core/transport/connectivity_state.h \
src/core/transport/metadata.h \
src/core/transport/metadata_batch.h \
+src/core/transport/static_metadata.h \
src/core/transport/transport.h \
src/core/transport/transport_impl.h \
src/core/census/aggregation.h \
@@ -1042,6 +1044,7 @@ src/core/transport/chttp2_transport.c \
src/core/transport/connectivity_state.c \
src/core/transport/metadata.c \
src/core/transport/metadata_batch.c \
+src/core/transport/static_metadata.c \
src/core/transport/transport.c \
src/core/transport/transport_op_string.c \
src/core/census/context.c \
diff --git a/tools/run_tests/post_tests_ruby.sh b/tools/run_tests/post_tests_ruby.sh
new file mode 100755
index 0000000000..66a9fbc534
--- /dev/null
+++ b/tools/run_tests/post_tests_ruby.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# 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.
+
+set -ex
+
+if [ "$CONFIG" != "gcov" ] ; then exit ; fi
+
+root=$(readlink -f $(dirname $0)/../..)
+out=$root/reports/ruby_ext_coverage
+tmp1=$(mktemp)
+tmp2=$(mktemp)
+cd $root
+lcov --capture --directory . --output-file $tmp1
+lcov --extract $tmp1 "$root/src/ruby/*" --output-file $tmp2
+genhtml $tmp2 --output-directory $out
+rm $tmp2
+rm $tmp1
+
+cp -rv $root/src/ruby/coverage $root/reports/ruby
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 47f949bdf3..f1595ac98f 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -322,7 +322,7 @@ class RubyLanguage(object):
return [['tools/run_tests/build_ruby.sh']]
def post_tests_steps(self):
- return []
+ return [['tools/run_tests/post_tests_ruby.sh']]
def makefile_name(self):
return 'Makefile'
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 1f9be91033..4ecffbe3ec 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -14380,6 +14380,7 @@
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
+ "src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",
@@ -14471,6 +14472,7 @@
"src/core/transport/connectivity_state.h",
"src/core/transport/metadata.h",
"src/core/transport/metadata_batch.h",
+ "src/core/transport/static_metadata.h",
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/tsi/fake_transport_security.h",
@@ -14557,6 +14559,7 @@
"src/core/client_config/uri_parser.c",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm.c",
+ "src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.c",
"src/core/compression/message_compress.h",
"src/core/debug/trace.c",
@@ -14758,6 +14761,8 @@
"src/core/transport/metadata.h",
"src/core/transport/metadata_batch.c",
"src/core/transport/metadata_batch.h",
+ "src/core/transport/static_metadata.c",
+ "src/core/transport/static_metadata.h",
"src/core/transport/transport.c",
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
@@ -14896,6 +14901,7 @@
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
+ "src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
"src/core/debug/trace.h",
"src/core/httpcli/format_request.h",
@@ -14978,6 +14984,7 @@
"src/core/transport/connectivity_state.h",
"src/core/transport/metadata.h",
"src/core/transport/metadata_batch.h",
+ "src/core/transport/static_metadata.h",
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h"
],
@@ -15059,6 +15066,7 @@
"src/core/client_config/uri_parser.c",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm.c",
+ "src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.c",
"src/core/compression/message_compress.h",
"src/core/debug/trace.c",
@@ -15234,6 +15242,8 @@
"src/core/transport/metadata.h",
"src/core/transport/metadata_batch.c",
"src/core/transport/metadata_batch.h",
+ "src/core/transport/static_metadata.c",
+ "src/core/transport/static_metadata.h",
"src/core/transport/transport.c",
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 72aad272f5..89ab6eda47 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -296,6 +296,7 @@
<ClInclude Include="..\..\..\src\core\client_config\subchannel_factory_decorators\add_channel_arg.h" />
<ClInclude Include="..\..\..\src\core\client_config\subchannel_factory_decorators\merge_channel_args.h" />
<ClInclude Include="..\..\..\src\core\client_config\uri_parser.h" />
+ <ClInclude Include="..\..\..\src\core\compression\algorithm_metadata.h" />
<ClInclude Include="..\..\..\src\core\compression\message_compress.h" />
<ClInclude Include="..\..\..\src\core\debug\trace.h" />
<ClInclude Include="..\..\..\src\core\httpcli\format_request.h" />
@@ -378,6 +379,7 @@
<ClInclude Include="..\..\..\src\core\transport\connectivity_state.h" />
<ClInclude Include="..\..\..\src\core\transport\metadata.h" />
<ClInclude Include="..\..\..\src\core\transport\metadata_batch.h" />
+ <ClInclude Include="..\..\..\src\core\transport\static_metadata.h" />
<ClInclude Include="..\..\..\src\core\transport\transport.h" />
<ClInclude Include="..\..\..\src\core\transport\transport_impl.h" />
<ClInclude Include="..\..\..\src\core\census\aggregation.h" />
@@ -675,6 +677,8 @@
</ClCompile>
<ClCompile Include="..\..\..\src\core\transport\metadata_batch.c">
</ClCompile>
+ <ClCompile Include="..\..\..\src\core\transport\static_metadata.c">
+ </ClCompile>
<ClCompile Include="..\..\..\src\core\transport\transport.c">
</ClCompile>
<ClCompile Include="..\..\..\src\core\transport\transport_op_string.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index b8dc05906d..a44d6e95bf 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -436,6 +436,9 @@
<ClCompile Include="..\..\..\src\core\transport\metadata_batch.c">
<Filter>src\core\transport</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\src\core\transport\static_metadata.c">
+ <Filter>src\core\transport</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\src\core\transport\transport.c">
<Filter>src\core\transport</Filter>
</ClCompile>
@@ -608,6 +611,9 @@
<ClInclude Include="..\..\..\src\core\client_config\uri_parser.h">
<Filter>src\core\client_config</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\src\core\compression\algorithm_metadata.h">
+ <Filter>src\core\compression</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\src\core\compression\message_compress.h">
<Filter>src\core\compression</Filter>
</ClInclude>
@@ -854,6 +860,9 @@
<ClInclude Include="..\..\..\src\core\transport\metadata_batch.h">
<Filter>src\core\transport</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\src\core\transport\static_metadata.h">
+ <Filter>src\core\transport</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\src\core\transport\transport.h">
<Filter>src\core\transport</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 548586ef2f..374220d952 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -275,6 +275,7 @@
<ClInclude Include="..\..\..\src\core\client_config\subchannel_factory_decorators\add_channel_arg.h" />
<ClInclude Include="..\..\..\src\core\client_config\subchannel_factory_decorators\merge_channel_args.h" />
<ClInclude Include="..\..\..\src\core\client_config\uri_parser.h" />
+ <ClInclude Include="..\..\..\src\core\compression\algorithm_metadata.h" />
<ClInclude Include="..\..\..\src\core\compression\message_compress.h" />
<ClInclude Include="..\..\..\src\core\debug\trace.h" />
<ClInclude Include="..\..\..\src\core\httpcli\format_request.h" />
@@ -357,6 +358,7 @@
<ClInclude Include="..\..\..\src\core\transport\connectivity_state.h" />
<ClInclude Include="..\..\..\src\core\transport\metadata.h" />
<ClInclude Include="..\..\..\src\core\transport\metadata_batch.h" />
+ <ClInclude Include="..\..\..\src\core\transport\static_metadata.h" />
<ClInclude Include="..\..\..\src\core\transport\transport.h" />
<ClInclude Include="..\..\..\src\core\transport\transport_impl.h" />
<ClInclude Include="..\..\..\src\core\census\aggregation.h" />
@@ -614,6 +616,8 @@
</ClCompile>
<ClCompile Include="..\..\..\src\core\transport\metadata_batch.c">
</ClCompile>
+ <ClCompile Include="..\..\..\src\core\transport\static_metadata.c">
+ </ClCompile>
<ClCompile Include="..\..\..\src\core\transport\transport.c">
</ClCompile>
<ClCompile Include="..\..\..\src\core\transport\transport_op_string.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 65e531016c..faadd82c4b 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -376,6 +376,9 @@
<ClCompile Include="..\..\..\src\core\transport\metadata_batch.c">
<Filter>src\core\transport</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\src\core\transport\static_metadata.c">
+ <Filter>src\core\transport</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\src\core\transport\transport.c">
<Filter>src\core\transport</Filter>
</ClCompile>
@@ -506,6 +509,9 @@
<ClInclude Include="..\..\..\src\core\client_config\uri_parser.h">
<Filter>src\core\client_config</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\src\core\compression\algorithm_metadata.h">
+ <Filter>src\core\compression</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\src\core\compression\message_compress.h">
<Filter>src\core\compression</Filter>
</ClInclude>
@@ -752,6 +758,9 @@
<ClInclude Include="..\..\..\src\core\transport\metadata_batch.h">
<Filter>src\core\transport</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\src\core\transport\static_metadata.h">
+ <Filter>src\core\transport</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\src\core\transport\transport.h">
<Filter>src\core\transport</Filter>
</ClInclude>