Merge pull request #4188 from ctiller/no-transport-metadata

Remove metadata contexts
pull/4247/head
Sree Kuchibhotla 9 years ago
commit 6fce197b3f
  1. 9
      BUILD
  2. 2
      Makefile
  3. 1
      binding.gyp
  4. 3
      build.yaml
  5. 5
      gRPC.podspec
  6. 3
      include/grpc/support/slice.h
  7. 18
      src/core/census/grpc_filter.c
  8. 2
      src/core/channel/channel_stack.c
  9. 2
      src/core/channel/channel_stack.h
  10. 3
      src/core/channel/client_channel.c
  11. 10
      src/core/channel/client_uchannel.c
  12. 74
      src/core/channel/compress_filter.c
  13. 98
      src/core/channel/http_client_filter.c
  14. 102
      src/core/channel/http_server_filter.c
  15. 11
      src/core/client_config/subchannel.c
  16. 5
      src/core/client_config/subchannel.h
  17. 50
      src/core/compression/algorithm.c
  18. 53
      src/core/compression/algorithm_metadata.h
  19. 31
      src/core/security/client_auth_filter.c
  20. 2
      src/core/security/server_auth_filter.c
  21. 10
      src/core/security/server_secure_chttp2.c
  22. 15
      src/core/support/slice.c
  23. 57
      src/core/surface/call.c
  24. 115
      src/core/surface/channel.c
  25. 11
      src/core/surface/channel.h
  26. 17
      src/core/surface/channel_create.c
  27. 2
      src/core/surface/init.c
  28. 15
      src/core/surface/lame_client.c
  29. 16
      src/core/surface/secure_channel_create.c
  30. 21
      src/core/surface/server.c
  31. 2
      src/core/surface/server.h
  32. 9
      src/core/surface/server_chttp2.c
  33. 10
      src/core/transport/chttp2/hpack_encoder.c
  34. 8
      src/core/transport/chttp2/hpack_encoder.h
  35. 26
      src/core/transport/chttp2/hpack_parser.c
  36. 3
      src/core/transport/chttp2/hpack_parser.h
  37. 7
      src/core/transport/chttp2/hpack_table.c
  38. 3
      src/core/transport/chttp2/hpack_table.h
  39. 4
      src/core/transport/chttp2/internal.h
  40. 17
      src/core/transport/chttp2/parsing.c
  41. 37
      src/core/transport/chttp2_transport.c
  42. 2
      src/core/transport/chttp2_transport.h
  43. 578
      src/core/transport/metadata.c
  44. 42
      src/core/transport/metadata.h
  45. 157
      src/core/transport/static_metadata.c
  46. 402
      src/core/transport/static_metadata.h
  47. 11
      test/core/bad_client/bad_client.c
  48. 9
      test/core/channel/channel_stack_test.c
  49. 3
      test/core/compression/compression_test.c
  50. 8
      test/core/compression/message_compress_test.c
  51. 27
      test/core/end2end/fixtures/h2_sockpair+trace.c
  52. 27
      test/core/end2end/fixtures/h2_sockpair.c
  53. 27
      test/core/end2end/fixtures/h2_sockpair_1byte.c
  54. 19
      test/core/end2end/fixtures/h2_uchannel.c
  55. 9
      test/core/transport/chttp2/hpack_encoder_test.c
  56. 15
      test/core/transport/chttp2/hpack_parser_test.c
  57. 33
      test/core/transport/chttp2/hpack_table_test.c
  58. 105
      test/core/transport/metadata_test.c
  59. 4
      test/proto/metrics.proto
  60. 310
      tools/codegen/core/gen_static_metadata.py
  61. 3
      tools/doxygen/Doxyfile.core.internal
  62. 10
      tools/run_tests/sources_and_headers.json
  63. 4
      vsprojects/vcxproj/grpc/grpc.vcxproj
  64. 9
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  65. 4
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  66. 9
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters

@ -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 \

@ -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',

@ -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

@ -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',

@ -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.

@ -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 = {

@ -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];

@ -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,

@ -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);

@ -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;

@ -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 = {

@ -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 = {

@ -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 = {

@ -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;
}

@ -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);

@ -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

@ -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 */

@ -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);
}
}

@ -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 */

@ -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

@ -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 {

@ -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(

@ -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) {

@ -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

@ -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");

@ -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);
}

@ -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, "

@ -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);

@ -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;

@ -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);

@ -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);
}

@ -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);
}

@ -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);

@ -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) {

@ -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);

@ -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);
}
}

@ -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);

@ -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;

@ -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;
}

@ -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;
}

@ -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,

@ -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;
}

@ -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 */

@ -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};

@ -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 */

@ -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);

@ -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;
}

@ -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;
}

@ -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;
}

@ -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);
}

@ -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);
}

@ -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);
}

@ -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");

@ -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]);
}

@ -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;
}

@ -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;
}

@ -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) {

@ -43,9 +43,7 @@ message GaugeResponse {
}
}
message GaugeRequest {
string name = 1;
}
message GaugeRequest { string name = 1; }
message EmptyMessage {
}

@ -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()

@ -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 \

@ -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",

@ -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">

@ -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>

@ -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">

@ -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>

Loading…
Cancel
Save