Remove metadata context from the channel stack
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index fa941a7..cbec63c 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -37,12 +37,15 @@
#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"
@@ -157,6 +160,11 @@
size_t mdtab_count;
size_t mdtab_free;
size_t mdtab_capacity;
+
+ /* cache slots */
+ gpr_atm cache_slots[GRPC_MDELEM_CACHE_SLOT_COUNT];
+ /* compression algorithm mdelems: one per algorithm bitmask */
+ gpr_atm compression_algorithm_mdelem[1 << GRPC_COMPRESS_ALGORITHMS_COUNT];
};
static void internal_string_ref(internal_string *s DEBUG_ARGS);
@@ -175,8 +183,10 @@
}
for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) {
grpc_mdelem *elem = &grpc_static_mdelem_table[i];
- grpc_mdstr *key = &grpc_static_mdstr_table[2 * i + 0];
- grpc_mdstr *value = &grpc_static_mdstr_table[2 * i + 1];
+ 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]];
*(grpc_mdstr **)&elem->key = key;
*(grpc_mdstr **)&elem->value = value;
}
@@ -304,6 +314,42 @@
(gpr_uint32)gpr_now(GPR_CLOCK_REALTIME).tv_nsec);
}
+static void drop_cached_elem(gpr_atm *slot) {
+ gpr_atm value = gpr_atm_no_barrier_load(slot);
+ gpr_atm_rel_store(slot, 0);
+ GRPC_MDELEM_UNREF((grpc_mdelem *)value);
+}
+
+void grpc_mdctx_drop_caches(grpc_mdctx *ctx) {
+ size_t i;
+ for (i = 0; i < GRPC_MDELEM_CACHE_SLOT_COUNT; i++) {
+ drop_cached_elem(&ctx->cache_slots[i]);
+ }
+ for (i = 0; i < GPR_ARRAY_SIZE(ctx->compression_algorithm_mdelem); i++) {
+ drop_cached_elem(&ctx->compression_algorithm_mdelem[i]);
+ }
+}
+
+static void set_cache(gpr_atm *slot, grpc_mdelem *elem) {
+ if (!gpr_atm_rel_cas(slot, 0, (gpr_atm)elem)) {
+ GRPC_MDELEM_UNREF(elem);
+ }
+}
+
+void grpc_mdctx_set_mdelem_cache(grpc_mdctx *ctx, grpc_mdelem_cache_slot slot,
+ grpc_mdelem *elem) {
+ set_cache(&ctx->cache_slots[slot], elem);
+}
+
+static grpc_mdelem *get_cache(gpr_atm *slot) {
+ return (grpc_mdelem *)gpr_atm_acq_load(slot);
+}
+
+grpc_mdelem *grpc_mdelem_from_cache(grpc_mdctx *ctx,
+ grpc_mdelem_cache_slot slot) {
+ return get_cache(&ctx->cache_slots[slot]);
+}
+
static void discard_metadata(grpc_mdctx *ctx) {
size_t i;
internal_metadata *next, *cur;
@@ -780,6 +826,7 @@
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)) {
@@ -838,6 +885,52 @@
return conforms_to(s, legal_header_bits);
}
+static grpc_mdelem *make_accept_encoding_mdelem_for_compression_algorithms(
+ grpc_mdctx *mdctx, gpr_uint32 algorithms) {
+ gpr_strvec sv;
+ int i;
+ char *str;
+ grpc_mdelem *out;
+
+ gpr_strvec_init(&sv);
+ for (i = 0; algorithms != 0; i++, algorithms >>= 1) {
+ if (algorithms & 1) {
+ char *name;
+ GPR_ASSERT(grpc_compression_algorithm_name((grpc_compression_algorithm)i,
+ &name));
+ if (sv.count) {
+ gpr_strvec_add(&sv, gpr_strdup(","));
+ }
+ gpr_strvec_add(&sv, gpr_strdup(name));
+ }
+ }
+ str = gpr_strvec_flatten(&sv, NULL);
+ out =
+ grpc_mdelem_from_metadata_strings(mdctx, GRPC_MDSTR_GRPC_ACCEPT_ENCODING,
+ grpc_mdstr_from_string(mdctx, str));
+ gpr_strvec_destroy(&sv);
+ gpr_free(str);
+ return out;
+}
+
+grpc_mdelem *grpc_accept_encoding_mdelem_from_compression_algorithms(
+ grpc_mdctx *ctx, gpr_uint32 algorithms) {
+ grpc_mdelem *ret;
+ gpr_atm *slot;
+ GPR_ASSERT(algorithms < GPR_ARRAY_SIZE(ctx->compression_algorithm_mdelem));
+
+ slot = &ctx->compression_algorithm_mdelem[algorithms];
+ ret = get_cache(slot);
+ if (ret == NULL) {
+ set_cache(slot, make_accept_encoding_mdelem_for_compression_algorithms(
+ ctx, algorithms));
+ ret = get_cache(slot);
+ GPR_ASSERT(ret != NULL);
+ }
+
+ return ret;
+}
+
int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s) {
/* TODO(ctiller): consider caching this */
return grpc_is_binary_header((const char *)GPR_SLICE_START_PTR(s->slice),