diff options
80 files changed, 1845 insertions, 1345 deletions
@@ -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", @@ -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> |