diff options
author | Vijay Pai <vpai@google.com> | 2018-03-01 11:48:29 -0800 |
---|---|---|
committer | Vijay Pai <vpai@google.com> | 2018-03-01 11:48:29 -0800 |
commit | b357f2f548884e0f1766b5b1c3b12e1aa64642cc (patch) | |
tree | 84a5f405562ee887fe79fb36b8a7fe42773933c6 /src/core/lib | |
parent | 2fe87b09055cd256cdce038c4c70d92b955c991b (diff) | |
parent | ccd1d55807bdb13b661dcf1d651468b2d98ff5af (diff) |
Merge branch 'master' into 2phase_thd
Diffstat (limited to 'src/core/lib')
23 files changed, 1224 insertions, 881 deletions
diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc index 444bb3d719..b02c5b9fb6 100644 --- a/src/core/lib/gpr/arena.cc +++ b/src/core/lib/gpr/arena.cc @@ -26,6 +26,49 @@ #include <grpc/support/atm.h> #include <grpc/support/log.h> +// Uncomment this to use a simple arena that simply allocates the +// requested amount of memory for each call to gpr_arena_alloc(). This +// effectively eliminates the efficiency gain of using an arena, but it +// may be useful for debugging purposes. +//#define SIMPLE_ARENA_FOR_DEBUGGING + +#ifdef SIMPLE_ARENA_FOR_DEBUGGING + +#include <grpc/support/sync.h> + +struct gpr_arena { + gpr_mu mu; + void** ptrs; + size_t num_ptrs; +}; + +gpr_arena* gpr_arena_create(size_t ignored_initial_size) { + gpr_arena* arena = (gpr_arena*)gpr_zalloc(sizeof(*arena)); + gpr_mu_init(&arena->mu); + return arena; +} + +size_t gpr_arena_destroy(gpr_arena* arena) { + gpr_mu_destroy(&arena->mu); + for (size_t i = 0; i < arena->num_ptrs; ++i) { + gpr_free(arena->ptrs[i]); + } + gpr_free(arena->ptrs); + gpr_free(arena); + return 1; // Value doesn't matter, since it won't be used. +} + +void* gpr_arena_alloc(gpr_arena* arena, size_t size) { + gpr_mu_lock(&arena->mu); + arena->ptrs = + (void**)gpr_realloc(arena->ptrs, sizeof(void*) * (arena->num_ptrs + 1)); + void* retval = arena->ptrs[arena->num_ptrs++] = gpr_zalloc(size); + gpr_mu_unlock(&arena->mu); + return retval; +} + +#else // SIMPLE_ARENA_FOR_DEBUGGING + // TODO(roth): We currently assume that all callers need alignment of 16 // bytes, which may be wrong in some cases. As part of converting the // arena API to C++, we should consider replacing gpr_arena_alloc() with a @@ -105,3 +148,5 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) { ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)); return ptr + start - z->size_begin; } + +#endif // SIMPLE_ARENA_FOR_DEBUGGING diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index 9e9e7f015f..a5bc8d8efc 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -24,6 +24,7 @@ #include <grpc/support/log.h> #include <grpc/support/sync.h> +#include <cinttypes> #include <memory> #include "src/core/lib/debug/trace.h" diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 02b115a40e..46bfaf7fb8 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -24,6 +24,8 @@ #include <grpc/support/log.h> #include <grpc/support/sync.h> +#include <cinttypes> + #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/debug_location.h" diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h index 72088e76ef..388e2ec410 100644 --- a/src/core/lib/gprpp/ref_counted_ptr.h +++ b/src/core/lib/gprpp/ref_counted_ptr.h @@ -33,6 +33,7 @@ template <typename T> class RefCountedPtr { public: RefCountedPtr() {} + RefCountedPtr(std::nullptr_t) {} // If value is non-null, we take ownership of a ref to it. explicit RefCountedPtr(T* value) { value_ = value; } diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc index 46311fa122..858ab6b41b 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.cc +++ b/src/core/lib/security/credentials/fake/fake_credentials.cc @@ -32,9 +32,6 @@ /* -- Fake transport security credentials. -- */ -#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \ - "grpc.fake_security.expected_targets" - static grpc_security_status fake_transport_security_create_security_connector( grpc_channel_credentials* c, grpc_call_credentials* call_creds, const char* target, const grpc_channel_args* args, diff --git a/src/core/lib/security/credentials/fake/fake_credentials.h b/src/core/lib/security/credentials/fake/fake_credentials.h index 5166e43167..e89e6e24cc 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.h +++ b/src/core/lib/security/credentials/fake/fake_credentials.h @@ -23,6 +23,9 @@ #include "src/core/lib/security/credentials/credentials.h" +#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \ + "grpc.fake_security.expected_targets" + /* -- Fake transport security credentials. -- */ /* Creates a fake transport security credentials object for testing. */ diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index b01fd6f769..3cc151bec7 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -39,9 +39,9 @@ #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/security/credentials/ssl/ssl_credentials.h" -#include "src/core/lib/security/transport/lb_targets_info.h" #include "src/core/lib/security/transport/secure_endpoint.h" #include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/lib/security/transport/target_authority_table.h" #include "src/core/tsi/fake_transport_security.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security_adapter.h" @@ -463,6 +463,15 @@ static bool fake_channel_check_call_host(grpc_channel_security_connector* sc, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) { + grpc_fake_channel_security_connector* c = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc); + if (c->is_lb_channel) { + // TODO(dgq): verify that the host (ie, authority header) matches that of + // the LB, as opposed to that of the backends. + } else { + // TODO(dgq): verify that the host (ie, authority header) matches that of + // the backend, not the LB's. + } return true; } @@ -514,7 +523,7 @@ grpc_channel_security_connector* grpc_fake_channel_security_connector_create( c->target = gpr_strdup(target); const char* expected_targets = grpc_fake_transport_get_expected_targets(args); c->expected_targets = gpr_strdup(expected_targets); - c->is_lb_channel = (grpc_lb_targets_info_find_in_args(args) != nullptr); + c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr; return &c->base; } diff --git a/src/core/lib/security/transport/lb_targets_info.cc b/src/core/lib/security/transport/lb_targets_info.cc deleted file mode 100644 index 155a91e556..0000000000 --- a/src/core/lib/security/transport/lb_targets_info.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include <grpc/support/port_platform.h> - -#include <grpc/support/log.h> - -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/security/transport/lb_targets_info.h" - -/* Channel arg key for the mapping of LB server addresses to their names for - * secure naming purposes. */ -#define GRPC_ARG_LB_SECURE_NAMING_MAP "grpc.lb_secure_naming_map" - -static void* targets_info_copy(void* p) { - return grpc_slice_hash_table_ref(static_cast<grpc_slice_hash_table*>(p)); -} -static void targets_info_destroy(void* p) { - grpc_slice_hash_table_unref(static_cast<grpc_slice_hash_table*>(p)); -} -static int targets_info_cmp(void* a, void* b) { - return grpc_slice_hash_table_cmp( - static_cast<const grpc_slice_hash_table*>(a), - static_cast<const grpc_slice_hash_table*>(b)); -} -static const grpc_arg_pointer_vtable server_to_balancer_names_vtable = { - targets_info_copy, targets_info_destroy, targets_info_cmp}; - -grpc_arg grpc_lb_targets_info_create_channel_arg( - grpc_slice_hash_table* targets_info) { - return grpc_channel_arg_pointer_create((char*)GRPC_ARG_LB_SECURE_NAMING_MAP, - targets_info, - &server_to_balancer_names_vtable); -} - -grpc_slice_hash_table* grpc_lb_targets_info_find_in_args( - const grpc_channel_args* args) { - const grpc_arg* targets_info_arg = - grpc_channel_args_find(args, GRPC_ARG_LB_SECURE_NAMING_MAP); - if (targets_info_arg != nullptr) { - GPR_ASSERT(targets_info_arg->type == GRPC_ARG_POINTER); - return static_cast<grpc_slice_hash_table*>( - targets_info_arg->value.pointer.p); - } - return nullptr; -} diff --git a/src/core/lib/security/transport/target_authority_table.cc b/src/core/lib/security/transport/target_authority_table.cc new file mode 100644 index 0000000000..1eeb557f6a --- /dev/null +++ b/src/core/lib/security/transport/target_authority_table.cc @@ -0,0 +1,75 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/support/port_platform.h> + +#include <grpc/support/log.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/transport/target_authority_table.h" + +// Channel arg key for the mapping of target addresses to their authorities. +#define GRPC_ARG_TARGET_AUTHORITY_TABLE "grpc.target_authority_table" + +namespace grpc_core { +namespace { + +void* target_authority_table_copy(void* p) { + TargetAuthorityTable* table = static_cast<TargetAuthorityTable*>(p); + // TODO(roth): When channel_args are converted to C++, pass the + // RefCountedPtr<> directly instead of managing the ref manually. + table->Ref().release(); + return p; +} +void target_authority_table_destroy(void* p) { + TargetAuthorityTable* table = static_cast<TargetAuthorityTable*>(p); + table->Unref(); +} +int target_authority_table_cmp(void* a, void* b) { + return TargetAuthorityTable::Cmp( + *static_cast<const TargetAuthorityTable*>(a), + *static_cast<const TargetAuthorityTable*>(b)); +} +const grpc_arg_pointer_vtable target_authority_table_arg_vtable = { + target_authority_table_copy, target_authority_table_destroy, + target_authority_table_cmp}; + +} // namespace + +grpc_arg CreateTargetAuthorityTableChannelArg(TargetAuthorityTable* table) { + return grpc_channel_arg_pointer_create((char*)GRPC_ARG_TARGET_AUTHORITY_TABLE, + table, + &target_authority_table_arg_vtable); +} + +TargetAuthorityTable* FindTargetAuthorityTableInArgs( + const grpc_channel_args* args) { + const grpc_arg* arg = + grpc_channel_args_find(args, GRPC_ARG_TARGET_AUTHORITY_TABLE); + if (arg != nullptr) { + if (arg->type == GRPC_ARG_POINTER) { + return static_cast<TargetAuthorityTable*>(arg->value.pointer.p); + } else { + gpr_log(GPR_ERROR, "value of " GRPC_ARG_TARGET_AUTHORITY_TABLE + " channel arg was not pointer type; ignoring"); + } + } + return nullptr; +} + +} // namespace grpc_core diff --git a/src/core/lib/security/transport/target_authority_table.h b/src/core/lib/security/transport/target_authority_table.h new file mode 100644 index 0000000000..a2e7dc6ac2 --- /dev/null +++ b/src/core/lib/security/transport/target_authority_table.h @@ -0,0 +1,40 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_TARGET_AUTHORITY_TABLE_H +#define GRPC_CORE_LIB_SECURITY_TRANSPORT_TARGET_AUTHORITY_TABLE_H + +#include <grpc/support/port_platform.h> + +#include "src/core/lib/slice/slice_hash_table.h" + +namespace grpc_core { + +/// A hash table mapping target addresses to authorities. +typedef SliceHashTable<UniquePtr<char>> TargetAuthorityTable; + +/// Returns a channel argument containing \a table. +grpc_arg CreateTargetAuthorityTableChannelArg(TargetAuthorityTable* table); + +/// Returns the target authority table from \a args or nullptr. +TargetAuthorityTable* FindTargetAuthorityTableInArgs( + const grpc_channel_args* args); + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_TARGET_AUTHORITY_TABLE_H */ diff --git a/src/core/lib/slice/slice_hash_table.cc b/src/core/lib/slice/slice_hash_table.cc deleted file mode 100644 index 9e32321636..0000000000 --- a/src/core/lib/slice/slice_hash_table.cc +++ /dev/null @@ -1,147 +0,0 @@ -// -// Copyright 2016 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#include <grpc/support/port_platform.h> - -#include "src/core/lib/slice/slice_hash_table.h" - -#include <stdbool.h> -#include <string.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> - -#include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/transport/metadata.h" - -struct grpc_slice_hash_table { - gpr_refcount refs; - void (*destroy_value)(void* value); - int (*value_cmp)(void* a, void* b); - size_t size; - size_t max_num_probes; - grpc_slice_hash_table_entry* entries; -}; - -static bool is_empty(grpc_slice_hash_table_entry* entry) { - return entry->value == nullptr; -} - -static void grpc_slice_hash_table_add(grpc_slice_hash_table* table, - grpc_slice key, void* value) { - GPR_ASSERT(value != nullptr); - const size_t hash = grpc_slice_hash(key); - for (size_t offset = 0; offset < table->size; ++offset) { - const size_t idx = (hash + offset) % table->size; - if (is_empty(&table->entries[idx])) { - table->entries[idx].key = key; - table->entries[idx].value = value; - // Keep track of the maximum number of probes needed, since this - // provides an upper bound for lookups. - if (offset > table->max_num_probes) table->max_num_probes = offset; - return; - } - } - GPR_ASSERT(false); // Table should never be full. -} - -grpc_slice_hash_table* grpc_slice_hash_table_create( - size_t num_entries, grpc_slice_hash_table_entry* entries, - void (*destroy_value)(void* value), int (*value_cmp)(void* a, void* b)) { - grpc_slice_hash_table* table = - static_cast<grpc_slice_hash_table*>(gpr_zalloc(sizeof(*table))); - gpr_ref_init(&table->refs, 1); - table->destroy_value = destroy_value; - table->value_cmp = value_cmp; - // Keep load factor low to improve performance of lookups. - table->size = num_entries * 2; - const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size; - table->entries = - static_cast<grpc_slice_hash_table_entry*>(gpr_zalloc(entry_size)); - for (size_t i = 0; i < num_entries; ++i) { - grpc_slice_hash_table_entry* entry = &entries[i]; - grpc_slice_hash_table_add(table, entry->key, entry->value); - } - return table; -} - -grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table) { - if (table != nullptr) gpr_ref(&table->refs); - return table; -} - -void grpc_slice_hash_table_unref(grpc_slice_hash_table* table) { - if (table != nullptr && gpr_unref(&table->refs)) { - for (size_t i = 0; i < table->size; ++i) { - grpc_slice_hash_table_entry* entry = &table->entries[i]; - if (!is_empty(entry)) { - grpc_slice_unref_internal(entry->key); - table->destroy_value(entry->value); - } - } - gpr_free(table->entries); - gpr_free(table); - } -} - -void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table, - const grpc_slice key) { - const size_t hash = grpc_slice_hash(key); - // We cap the number of probes at the max number recorded when - // populating the table. - for (size_t offset = 0; offset <= table->max_num_probes; ++offset) { - const size_t idx = (hash + offset) % table->size; - if (is_empty(&table->entries[idx])) break; - if (grpc_slice_eq(table->entries[idx].key, key)) { - return table->entries[idx].value; - } - } - return nullptr; // Not found. -} - -static int pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); } -int grpc_slice_hash_table_cmp(const grpc_slice_hash_table* a, - const grpc_slice_hash_table* b) { - int (*const value_cmp_fn_a)(void* a, void* b) = - a->value_cmp != nullptr ? a->value_cmp : pointer_cmp; - int (*const value_cmp_fn_b)(void* a, void* b) = - b->value_cmp != nullptr ? b->value_cmp : pointer_cmp; - // Compare value_fns - const int value_fns_cmp = - GPR_ICMP((void*)value_cmp_fn_a, (void*)value_cmp_fn_b); - if (value_fns_cmp != 0) return value_fns_cmp; - // Compare sizes - if (a->size < b->size) return -1; - if (a->size > b->size) return 1; - // Compare rows. - for (size_t i = 0; i < a->size; ++i) { - if (is_empty(&a->entries[i])) { - if (!is_empty(&b->entries[i])) { - return -1; // a empty but b non-empty - } - continue; // both empty, no need to check key or value - } else if (is_empty(&b->entries[i])) { - return 1; // a non-empty but b empty - } - // neither entry is empty - const int key_cmp = grpc_slice_cmp(a->entries[i].key, b->entries[i].key); - if (key_cmp != 0) return key_cmp; - const int value_cmp = - value_cmp_fn_a(a->entries[i].value, b->entries[i].value); - if (value_cmp != 0) return value_cmp; - } - return 0; -} diff --git a/src/core/lib/slice/slice_hash_table.h b/src/core/lib/slice/slice_hash_table.h index 819bb3b5bc..fbe9cc58e8 100644 --- a/src/core/lib/slice/slice_hash_table.h +++ b/src/core/lib/slice/slice_hash_table.h @@ -19,52 +19,183 @@ #include <grpc/support/port_platform.h> -#include "src/core/lib/transport/metadata.h" +#include <string.h> -/** Hash table implementation. - * - * This implementation uses open addressing - * (https://en.wikipedia.org/wiki/Open_addressing) with linear - * probing (https://en.wikipedia.org/wiki/Linear_probing). - * - * The keys are \a grpc_slice objects. The values are arbitrary pointers - * with a common destroy function. - * - * Hash tables are intentionally immutable, to avoid the need for locking. - */ +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/slice/slice_internal.h" + +/// Hash table implementation. +/// +/// This implementation uses open addressing +/// (https://en.wikipedia.org/wiki/Open_addressing) with linear +/// probing (https://en.wikipedia.org/wiki/Linear_probing). +/// +/// The keys are \a grpc_slice objects. The values can be any type. +/// +/// Hash tables are intentionally immutable, to avoid the need for locking. + +namespace grpc_core { + +template <typename T> +class SliceHashTable : public RefCounted<SliceHashTable<T>> { + public: + struct Entry { + grpc_slice key; + T value; + bool is_set; + }; + + // Function for comparing values. + // TODO(roth): Eliminate this and the Cmp() method from this API once + // grpc_channel_args is redesigned to require that keys are unique. + typedef int (*ValueCmp)(const T&, const T&); + + /// Creates a new hash table containing \a entries, which is an array + /// of length \a num_entries. Takes ownership of all keys and values in \a + /// entries. If not null, \a value_cmp will be used to compare values in + /// the context of \a Cmp(). If null, raw pointer (\a GPR_ICMP) comparison + /// will be used. + static RefCountedPtr<SliceHashTable> Create(size_t num_entries, + Entry* entries, + ValueCmp value_cmp); + + /// Returns the value from the table associated with \a key. + /// Returns null if \a key is not found. + const T* Get(const grpc_slice& key) const; + + /// Compares \a a vs. \a b. + /// A table is considered "smaller" (resp. "greater") if: + /// - GPR_ICMP(a->value_cmp, b->value_cmp) < 1 (resp. > 1), + /// - else, it contains fewer (resp. more) entries, + /// - else, if strcmp(a_key, b_key) < 1 (resp. > 1), + /// - else, if value_cmp(a_value, b_value) < 1 (resp. > 1). + static int Cmp(const SliceHashTable& a, const SliceHashTable& b); + + private: + // So New() can call our private ctor. + template <typename T2, typename... Args> + friend T2* New(Args&&... args); + + SliceHashTable(size_t num_entries, Entry* entries, ValueCmp value_cmp); + virtual ~SliceHashTable(); + + void Add(grpc_slice key, T& value); + + // Default value comparison function, if none specified by caller. + static int DefaultValueCmp(const T& a, const T& b) { return GPR_ICMP(a, b); } + + const ValueCmp value_cmp_; + const size_t size_; + size_t max_num_probes_; + Entry* entries_; +}; + +// +// implementation -- no user-serviceable parts below +// + +template <typename T> +RefCountedPtr<SliceHashTable<T>> SliceHashTable<T>::Create(size_t num_entries, + Entry* entries, + ValueCmp value_cmp) { + return MakeRefCounted<SliceHashTable<T>>(num_entries, entries, value_cmp); +} + +template <typename T> +SliceHashTable<T>::SliceHashTable(size_t num_entries, Entry* entries, + ValueCmp value_cmp) + : value_cmp_(value_cmp), + // Keep load factor low to improve performance of lookups. + size_(num_entries * 2), + max_num_probes_(0) { + entries_ = static_cast<Entry*>(gpr_zalloc(sizeof(Entry) * size_)); + for (size_t i = 0; i < num_entries; ++i) { + Entry* entry = &entries[i]; + Add(entry->key, entry->value); + } +} + +template <typename T> +SliceHashTable<T>::~SliceHashTable() { + for (size_t i = 0; i < size_; ++i) { + Entry& entry = entries_[i]; + if (entry.is_set) { + grpc_slice_unref_internal(entry.key); + entry.value.~T(); + } + } + gpr_free(entries_); +} + +template <typename T> +void SliceHashTable<T>::Add(grpc_slice key, T& value) { + const size_t hash = grpc_slice_hash(key); + for (size_t offset = 0; offset < size_; ++offset) { + const size_t idx = (hash + offset) % size_; + if (!entries_[idx].is_set) { + entries_[idx].is_set = true; + entries_[idx].key = key; + entries_[idx].value = std::move(value); + // Keep track of the maximum number of probes needed, since this + // provides an upper bound for lookups. + if (offset > max_num_probes_) max_num_probes_ = offset; + return; + } + } + GPR_ASSERT(false); // Table should never be full. +} + +template <typename T> +const T* SliceHashTable<T>::Get(const grpc_slice& key) const { + const size_t hash = grpc_slice_hash(key); + // We cap the number of probes at the max number recorded when + // populating the table. + for (size_t offset = 0; offset <= max_num_probes_; ++offset) { + const size_t idx = (hash + offset) % size_; + if (!entries_[idx].is_set) break; + if (grpc_slice_eq(entries_[idx].key, key)) { + return &entries_[idx].value; + } + } + return nullptr; // Not found. +} + +template <typename T> +int SliceHashTable<T>::Cmp(const SliceHashTable& a, const SliceHashTable& b) { + ValueCmp value_cmp_a = + a.value_cmp_ != nullptr ? a.value_cmp_ : DefaultValueCmp; + ValueCmp value_cmp_b = + b.value_cmp_ != nullptr ? b.value_cmp_ : DefaultValueCmp; + // Compare value_fns + const int value_fns_cmp = GPR_ICMP((void*)value_cmp_a, (void*)value_cmp_b); + if (value_fns_cmp != 0) return value_fns_cmp; + // Compare sizes + if (a.size_ < b.size_) return -1; + if (a.size_ > b.size_) return 1; + // Compare rows. + for (size_t i = 0; i < a.size_; ++i) { + if (!a.entries_[i].is_set) { + if (b.entries_[i].is_set) { + return -1; // a empty but b non-empty + } + continue; // both empty, no need to check key or value + } else if (!b.entries_[i].is_set) { + return 1; // a non-empty but b empty + } + // neither entry is empty + const int key_cmp = grpc_slice_cmp(a.entries_[i].key, b.entries_[i].key); + if (key_cmp != 0) return key_cmp; + const int value_cmp = value_cmp_a(a.entries_[i].value, b.entries_[i].value); + if (value_cmp != 0) return value_cmp; + } + return 0; +} -typedef struct grpc_slice_hash_table grpc_slice_hash_table; - -typedef struct grpc_slice_hash_table_entry { - grpc_slice key; - void* value; /* Must not be NULL. */ -} grpc_slice_hash_table_entry; - -/** Creates a new hash table of containing \a entries, which is an array - of length \a num_entries. Takes ownership of all keys and values in \a - entries. Values will be cleaned up via \a destroy_value(). If not NULL, \a - value_cmp will be used to compare values in the context of \a - grpc_slice_hash_table_cmp. If NULL, raw pointer (\a GPR_ICMP) comparison - will be used. */ -grpc_slice_hash_table* grpc_slice_hash_table_create( - size_t num_entries, grpc_slice_hash_table_entry* entries, - void (*destroy_value)(void* value), int (*value_cmp)(void* a, void* b)); - -grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table); -void grpc_slice_hash_table_unref(grpc_slice_hash_table* table); - -/** Returns the value from \a table associated with \a key. - Returns NULL if \a key is not found. */ -void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table, - const grpc_slice key); - -/** Compares \a a vs. \a b. - * A table is considered "smaller" (resp. "greater") if: - * - GPR_ICMP(a->value_cmp, b->value_cmp) < 1 (resp. > 1), - * - else, it contains fewer (resp. more) entries, - * - else, if strcmp(a_key, b_key) < 1 (resp. > 1), - * - else, if value_cmp(a_value, b_value) < 1 (resp. > 1). */ -int grpc_slice_hash_table_cmp(const grpc_slice_hash_table* a, - const grpc_slice_hash_table* b); +} // namespace grpc_core #endif /* GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H */ diff --git a/src/core/lib/slice/slice_weak_hash_table.h b/src/core/lib/slice/slice_weak_hash_table.h new file mode 100644 index 0000000000..9d0ddfc2d2 --- /dev/null +++ b/src/core/lib/slice/slice_weak_hash_table.h @@ -0,0 +1,105 @@ +/* + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRPC_CORE_LIB_SLICE_SLICE_WEAK_HASH_TABLE_H +#define GRPC_CORE_LIB_SLICE_SLICE_WEAK_HASH_TABLE_H + +#include <grpc/support/port_platform.h> + +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/slice/slice_internal.h" + +/// Weak hash table implementation. +/// +/// This entries in this table are weak: an entry may be removed at any time due +/// to a number of reasons: memory pressure, hash collisions, etc. +/// +/// The keys are \a grpc_slice objects. The values are of arbitrary type. +/// +/// This class is thread unsafe. It's the caller's responsibility to ensure +/// proper locking when accessing its methods. + +namespace grpc_core { + +template <typename T, size_t Size> +class SliceWeakHashTable : public RefCounted<SliceWeakHashTable<T, Size>> { + public: + /// Creates a new table of at most \a size entries. + static RefCountedPtr<SliceWeakHashTable> Create() { + return MakeRefCounted<SliceWeakHashTable<T, Size>>(); + } + + /// Add a mapping from \a key to \a value, taking ownership of \a key. This + /// operation will always succeed. It may discard older entries. + void Add(grpc_slice key, T value) { + const size_t idx = grpc_slice_hash(key) % Size; + entries_[idx].Set(key, std::move(value)); + return; + } + + /// Returns the value from the table associated with / \a key or null if not + /// found. + const T* Get(const grpc_slice key) const { + const size_t idx = grpc_slice_hash(key) % Size; + const auto& entry = entries_[idx]; + return grpc_slice_eq(entry.key(), key) ? entry.value() : nullptr; + } + + private: + // So New() can call our private ctor. + template <typename T2, typename... Args> + friend T2* New(Args&&... args); + + SliceWeakHashTable() = default; + ~SliceWeakHashTable() = default; + + /// The type of the table "rows". + class Entry { + public: + Entry() = default; + ~Entry() { + if (is_set_) grpc_slice_unref_internal(key_); + } + grpc_slice key() const { return key_; } + + /// Return the entry's value, or null if unset. + const T* value() const { + if (!is_set_) return nullptr; + return &value_; + } + + /// Set the \a key and \a value (which is moved) for the entry. + void Set(grpc_slice key, T&& value) { + if (is_set_) grpc_slice_unref_internal(key_); + key_ = key; + value_ = std::move(value); + is_set_ = true; + } + + private: + grpc_slice key_; + T value_; + bool is_set_ = false; + }; + + Entry entries_[Size]; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_SLICE_SLICE_WEAK_HASH_TABLE_H */ diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 3df745652a..c4844da318 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -50,6 +50,7 @@ #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/status_metadata.h" #include "src/core/lib/transport/transport.h" /** The maximum number of concurrent batches possible. @@ -976,32 +977,6 @@ static int prepare_application_metadata(grpc_call* call, int count, return 1; } -/* we offset status by a small amount when storing it into transport metadata - as metadata cannot store a 0 value (which is used as OK for grpc_status_codes - */ -#define STATUS_OFFSET 1 -static void destroy_status(void* ignored) {} - -static uint32_t decode_status(grpc_mdelem md) { - uint32_t status; - void* user_data; - if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) return 0; - if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_1)) return 1; - if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_2)) return 2; - user_data = grpc_mdelem_get_user_data(md, destroy_status); - if (user_data != nullptr) { - status = (static_cast<uint32_t>((intptr_t)user_data)) - STATUS_OFFSET; - } else { - if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(md), &status)) { - status = GRPC_STATUS_UNKNOWN; /* could not parse status code */ - } - grpc_mdelem_set_user_data( - md, destroy_status, - (void*)static_cast<intptr_t>(status + STATUS_OFFSET)); - } - return status; -} - static grpc_message_compression_algorithm decode_message_compression( grpc_mdelem md) { grpc_message_compression_algorithm algorithm = @@ -1093,7 +1068,8 @@ static void recv_initial_filter(grpc_call* call, grpc_metadata_batch* b) { static void recv_trailing_filter(void* args, grpc_metadata_batch* b) { grpc_call* call = static_cast<grpc_call*>(args); if (b->idx.named.grpc_status != nullptr) { - uint32_t status_code = decode_status(b->idx.named.grpc_status->md); + grpc_status_code status_code = + grpc_get_status_code_from_metadata(b->idx.named.grpc_status->md); grpc_error* error = status_code == GRPC_STATUS_OK ? GRPC_ERROR_NONE diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index b23f516516..49740fcd1e 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -303,3 +303,27 @@ grpc_error* grpc_metadata_batch_filter(grpc_metadata_batch* batch, } return error; } + +void grpc_metadata_batch_copy(grpc_metadata_batch* src, + grpc_metadata_batch* dst, + grpc_linked_mdelem* storage) { + grpc_metadata_batch_init(dst); + dst->deadline = src->deadline; + size_t i = 0; + for (grpc_linked_mdelem* elem = src->list.head; elem != nullptr; + elem = elem->next) { + grpc_error* error = grpc_metadata_batch_add_tail(dst, &storage[i++], + GRPC_MDELEM_REF(elem->md)); + // The only way that grpc_metadata_batch_add_tail() can fail is if + // there's a duplicate entry for a callout. However, that can't be + // the case here, because we would not have been allowed to create + // a source batch that had that kind of conflict. + GPR_ASSERT(error == GRPC_ERROR_NONE); + } +} + +void grpc_metadata_batch_move(grpc_metadata_batch* src, + grpc_metadata_batch* dst) { + *dst = *src; + grpc_metadata_batch_init(src); +} diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index 06fc9ade7e..3876063b52 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -137,4 +137,13 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch* comd); } while (0) #endif +/// Copies \a src to \a dst. \a storage must point to an array of +/// \a grpc_linked_mdelem structs of at least the same size as \a src. +void grpc_metadata_batch_copy(grpc_metadata_batch* src, + grpc_metadata_batch* dst, + grpc_linked_mdelem* storage); + +void grpc_metadata_batch_move(grpc_metadata_batch* src, + grpc_metadata_batch* dst); + #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H */ diff --git a/src/core/lib/transport/service_config.cc b/src/core/lib/transport/service_config.cc index b1d727419d..e1a55d98ab 100644 --- a/src/core/lib/transport/service_config.cc +++ b/src/core/lib/transport/service_config.cc @@ -31,74 +31,30 @@ #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" -// The main purpose of the code here is to parse the service config in -// JSON form, which will look like this: -// -// { -// "loadBalancingPolicy": "string", // optional -// "methodConfig": [ // array of one or more method_config objects -// { -// "name": [ // array of one or more name objects -// { -// "service": "string", // required -// "method": "string", // optional -// } -// ], -// // remaining fields are optional. -// // see https://developers.google.com/protocol-buffers/docs/proto3#json -// // for format details. -// "waitForReady": bool, -// "timeout": "duration_string", -// "maxRequestMessageBytes": "int64_string", -// "maxResponseMessageBytes": "int64_string", -// } -// ] -// } - -struct grpc_service_config { - char* json_string; // Underlying storage for json_tree. - grpc_json* json_tree; -}; +namespace grpc_core { -grpc_service_config* grpc_service_config_create(const char* json_string) { - grpc_service_config* service_config = - static_cast<grpc_service_config*>(gpr_malloc(sizeof(*service_config))); - service_config->json_string = gpr_strdup(json_string); - service_config->json_tree = - grpc_json_parse_string(service_config->json_string); - if (service_config->json_tree == nullptr) { +UniquePtr<ServiceConfig> ServiceConfig::Create(const char* json) { + UniquePtr<char> json_string(gpr_strdup(json)); + grpc_json* json_tree = grpc_json_parse_string(json_string.get()); + if (json_tree == nullptr) { gpr_log(GPR_INFO, "failed to parse JSON for service config"); - gpr_free(service_config->json_string); - gpr_free(service_config); return nullptr; } - return service_config; + return MakeUnique<ServiceConfig>(std::move(json_string), json_tree); } -void grpc_service_config_destroy(grpc_service_config* service_config) { - grpc_json_destroy(service_config->json_tree); - gpr_free(service_config->json_string); - gpr_free(service_config); -} +ServiceConfig::ServiceConfig(UniquePtr<char> json_string, grpc_json* json_tree) + : json_string_(std::move(json_string)), json_tree_(json_tree) {} -void grpc_service_config_parse_global_params( - const grpc_service_config* service_config, - void (*process_json)(const grpc_json* json, void* arg), void* arg) { - const grpc_json* json = service_config->json_tree; - if (json->type != GRPC_JSON_OBJECT || json->key != nullptr) return; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) return; - if (strcmp(field->key, "methodConfig") == 0) continue; - process_json(field, arg); - } -} +ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } -const char* grpc_service_config_get_lb_policy_name( - const grpc_service_config* service_config) { - const grpc_json* json = service_config->json_tree; - if (json->type != GRPC_JSON_OBJECT || json->key != nullptr) return nullptr; +const char* ServiceConfig::GetLoadBalancingPolicyName() const { + if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { + return nullptr; + } const char* lb_policy_name = nullptr; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { + for (grpc_json* field = json_tree_->child; field != nullptr; + field = field->next) { if (field->key == nullptr) return nullptr; if (strcmp(field->key, "loadBalancingPolicy") == 0) { if (lb_policy_name != nullptr) return nullptr; // Duplicate. @@ -109,8 +65,7 @@ const char* grpc_service_config_get_lb_policy_name( return lb_policy_name; } -// Returns the number of names specified in the method config \a json. -static size_t count_names_in_method_config_json(grpc_json* json) { +size_t ServiceConfig::CountNamesInMethodConfig(grpc_json* json) { size_t num_names = 0; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key != nullptr && strcmp(field->key, "name") == 0) { @@ -124,9 +79,7 @@ static size_t count_names_in_method_config_json(grpc_json* json) { return num_names; } -// Returns a path string for the JSON name object specified by \a json. -// Returns NULL on error. Caller takes ownership of result. -static char* parse_json_method_name(grpc_json* json) { +UniquePtr<char> ServiceConfig::ParseJsonMethodName(grpc_json* json) { if (json->type != GRPC_JSON_OBJECT) return nullptr; const char* service_name = nullptr; const char* method_name = nullptr; @@ -147,116 +100,7 @@ static char* parse_json_method_name(grpc_json* json) { char* path; gpr_asprintf(&path, "/%s/%s", service_name, method_name == nullptr ? "*" : method_name); - return path; + return UniquePtr<char>(path); } -// Parses the method config from \a json. Adds an entry to \a entries for -// each name found, incrementing \a idx for each entry added. -// Returns false on error. -static bool parse_json_method_config( - grpc_json* json, void* (*create_value)(const grpc_json* method_config_json), - void* (*ref_value)(void* value), void (*unref_value)(void* value), - grpc_slice_hash_table_entry* entries, size_t* idx) { - // Construct value. - void* method_config = create_value(json); - if (method_config == nullptr) return false; - // Construct list of paths. - bool success = false; - gpr_strvec paths; - gpr_strvec_init(&paths); - for (grpc_json* child = json->child; child != nullptr; child = child->next) { - if (child->key == nullptr) continue; - if (strcmp(child->key, "name") == 0) { - if (child->type != GRPC_JSON_ARRAY) goto done; - for (grpc_json* name = child->child; name != nullptr; name = name->next) { - char* path = parse_json_method_name(name); - if (path == nullptr) goto done; - gpr_strvec_add(&paths, path); - } - } - } - if (paths.count == 0) goto done; // No names specified. - // Add entry for each path. - for (size_t i = 0; i < paths.count; ++i) { - entries[*idx].key = grpc_slice_from_copied_string(paths.strs[i]); - entries[*idx].value = ref_value(method_config); - ++*idx; - } - success = true; -done: - unref_value(method_config); - gpr_strvec_destroy(&paths); - return success; -} - -grpc_slice_hash_table* grpc_service_config_create_method_config_table( - const grpc_service_config* service_config, - void* (*create_value)(const grpc_json* method_config_json), - void* (*ref_value)(void* value), void (*unref_value)(void* value)) { - const grpc_json* json = service_config->json_tree; - // Traverse parsed JSON tree. - if (json->type != GRPC_JSON_OBJECT || json->key != nullptr) return nullptr; - size_t num_entries = 0; - grpc_slice_hash_table_entry* entries = nullptr; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) return nullptr; - if (strcmp(field->key, "methodConfig") == 0) { - if (entries != nullptr) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_ARRAY) return nullptr; - // Find number of entries. - for (grpc_json* method = field->child; method != nullptr; - method = method->next) { - size_t count = count_names_in_method_config_json(method); - if (count <= 0) return nullptr; - num_entries += count; - } - // Populate method config table entries. - entries = static_cast<grpc_slice_hash_table_entry*>( - gpr_malloc(num_entries * sizeof(grpc_slice_hash_table_entry))); - size_t idx = 0; - for (grpc_json* method = field->child; method != nullptr; - method = method->next) { - if (!parse_json_method_config(method, create_value, ref_value, - unref_value, entries, &idx)) { - for (size_t i = 0; i < idx; ++i) { - grpc_slice_unref_internal(entries[i].key); - unref_value(entries[i].value); - } - gpr_free(entries); - return nullptr; - } - } - GPR_ASSERT(idx == num_entries); - } - } - // Instantiate method config table. - grpc_slice_hash_table* method_config_table = nullptr; - if (entries != nullptr) { - method_config_table = grpc_slice_hash_table_create(num_entries, entries, - unref_value, nullptr); - gpr_free(entries); - } - return method_config_table; -} - -void* grpc_method_config_table_get(const grpc_slice_hash_table* table, - grpc_slice path) { - void* value = grpc_slice_hash_table_get(table, path); - // If we didn't find a match for the path, try looking for a wildcard - // entry (i.e., change "/service/method" to "/service/*"). - if (value == nullptr) { - char* path_str = grpc_slice_to_c_string(path); - const char* sep = strrchr(path_str, '/') + 1; - const size_t len = static_cast<size_t>(sep - path_str); - char* buf = static_cast<char*>(gpr_malloc(len + 2)); // '*' and NUL - memcpy(buf, path_str, len); - buf[len] = '*'; - buf[len + 1] = '\0'; - grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); - gpr_free(buf); - value = grpc_slice_hash_table_get(table, wildcard_path); - grpc_slice_unref_internal(wildcard_path); - gpr_free(path_str); - } - return value; -} +} // namespace grpc_core diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h index 6517f36802..a65b267d46 100644 --- a/src/core/lib/transport/service_config.h +++ b/src/core/lib/transport/service_config.h @@ -20,44 +20,230 @@ #include <grpc/support/port_platform.h> #include <grpc/impl/codegen/grpc_types.h> +#include <grpc/support/string_util.h> +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/json/json.h" #include "src/core/lib/slice/slice_hash_table.h" -typedef struct grpc_service_config grpc_service_config; - -grpc_service_config* grpc_service_config_create(const char* json_string); -void grpc_service_config_destroy(grpc_service_config* service_config); - -/// Invokes \a process_json() for each global parameter in the service -/// config. \a arg is passed as the second argument to \a process_json(). -void grpc_service_config_parse_global_params( - const grpc_service_config* service_config, - void (*process_json)(const grpc_json* json, void* arg), void* arg); - -/// Gets the LB policy name from \a service_config. -/// Returns NULL if no LB policy name was specified. -/// Caller does NOT take ownership. -const char* grpc_service_config_get_lb_policy_name( - const grpc_service_config* service_config); - -/// Creates a method config table based on the data in \a json. -/// The table's keys are request paths. The table's value type is -/// returned by \a create_value(), based on data parsed from the JSON tree. -/// \a ref_value() and \a unref_value() are used to ref and unref values. -/// Returns NULL on error. -grpc_slice_hash_table* grpc_service_config_create_method_config_table( - const grpc_service_config* service_config, - void* (*create_value)(const grpc_json* method_config_json), - void* (*ref_value)(void* value), void (*unref_value)(void* value)); - -/// A helper function for looking up values in the table returned by -/// \a grpc_service_config_create_method_config_table(). -/// Gets the method config for the specified \a path, which should be of -/// the form "/service/method". -/// Returns NULL if the method has no config. -/// Caller does NOT own a reference to the result. -void* grpc_method_config_table_get(const grpc_slice_hash_table* table, - grpc_slice path); +// The main purpose of the code here is to parse the service config in +// JSON form, which will look like this: +// +// { +// "loadBalancingPolicy": "string", // optional +// "methodConfig": [ // array of one or more method_config objects +// { +// "name": [ // array of one or more name objects +// { +// "service": "string", // required +// "method": "string", // optional +// } +// ], +// // remaining fields are optional. +// // see +// https://developers.google.com/protocol-buffers/docs/proto3#json +// // for format details. +// "waitForReady": bool, +// "timeout": "duration_string", +// "maxRequestMessageBytes": "int64_string", +// "maxResponseMessageBytes": "int64_string", +// } +// ] +// } + +namespace grpc_core { + +class ServiceConfig { + public: + /// Creates a new service config from parsing \a json_string. + /// Returns null on parse error. + static UniquePtr<ServiceConfig> Create(const char* json); + + ~ServiceConfig(); + + /// Invokes \a process_json() for each global parameter in the service + /// config. \a arg is passed as the second argument to \a process_json(). + template <typename T> + using ProcessJson = void (*)(const grpc_json*, T*); + template <typename T> + void ParseGlobalParams(ProcessJson<T> process_json, T* arg) const; + + /// Gets the LB policy name from \a service_config. + /// Returns NULL if no LB policy name was specified. + /// Caller does NOT take ownership. + const char* GetLoadBalancingPolicyName() const; + + /// Creates a method config table based on the data in \a json. + /// The table's keys are request paths. The table's value type is + /// returned by \a create_value(), based on data parsed from the JSON tree. + /// Returns null on error. + template <typename T> + using CreateValue = RefCountedPtr<T> (*)(const grpc_json* method_config_json); + template <typename T> + RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> CreateMethodConfigTable( + CreateValue<T> create_value); + + /// A helper function for looking up values in the table returned by + /// \a CreateMethodConfigTable(). + /// Gets the method config for the specified \a path, which should be of + /// the form "/service/method". + /// Returns null if the method has no config. + /// Caller does NOT own a reference to the result. + template <typename T> + static RefCountedPtr<T> MethodConfigTableLookup( + const SliceHashTable<RefCountedPtr<T>>& table, grpc_slice path); + + private: + // So New() can call our private ctor. + template <typename T, typename... Args> + friend T* New(Args&&... args); + + // Takes ownership of \a json_tree. + ServiceConfig(UniquePtr<char> json_string, grpc_json* json_tree); + + // Returns the number of names specified in the method config \a json. + static size_t CountNamesInMethodConfig(grpc_json* json); + + // Returns a path string for the JSON name object specified by \a json. + // Returns null on error. + static UniquePtr<char> ParseJsonMethodName(grpc_json* json); + + // Parses the method config from \a json. Adds an entry to \a entries for + // each name found, incrementing \a idx for each entry added. + // Returns false on error. + template <typename T> + static bool ParseJsonMethodConfig( + grpc_json* json, CreateValue<T> create_value, + typename SliceHashTable<RefCountedPtr<T>>::Entry* entries, size_t* idx); + + UniquePtr<char> json_string_; // Underlying storage for json_tree. + grpc_json* json_tree_; +}; + +// +// implementation -- no user-serviceable parts below +// + +template <typename T> +void ServiceConfig::ParseGlobalParams(ProcessJson<T> process_json, + T* arg) const { + if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { + return; + } + for (grpc_json* field = json_tree_->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) return; + if (strcmp(field->key, "methodConfig") == 0) continue; + process_json(field, arg); + } +} + +template <typename T> +bool ServiceConfig::ParseJsonMethodConfig( + grpc_json* json, CreateValue<T> create_value, + typename SliceHashTable<RefCountedPtr<T>>::Entry* entries, size_t* idx) { + // Construct value. + RefCountedPtr<T> method_config = create_value(json); + if (method_config == nullptr) return false; + // Construct list of paths. + InlinedVector<UniquePtr<char>, 10> paths; + for (grpc_json* child = json->child; child != nullptr; child = child->next) { + if (child->key == nullptr) continue; + if (strcmp(child->key, "name") == 0) { + if (child->type != GRPC_JSON_ARRAY) return false; + for (grpc_json* name = child->child; name != nullptr; name = name->next) { + UniquePtr<char> path = ParseJsonMethodName(name); + if (path == nullptr) return false; + paths.push_back(std::move(path)); + } + } + } + if (paths.size() == 0) return false; // No names specified. + // Add entry for each path. + for (size_t i = 0; i < paths.size(); ++i) { + entries[*idx].key = grpc_slice_from_copied_string(paths[i].get()); + entries[*idx].value = method_config; // Takes a new ref. + ++*idx; + } + // Success. + return true; +} + +template <typename T> +RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> +ServiceConfig::CreateMethodConfigTable(CreateValue<T> create_value) { + // Traverse parsed JSON tree. + if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { + return nullptr; + } + size_t num_entries = 0; + typename SliceHashTable<RefCountedPtr<T>>::Entry* entries = nullptr; + for (grpc_json* field = json_tree_->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) return nullptr; + if (strcmp(field->key, "methodConfig") == 0) { + if (entries != nullptr) return nullptr; // Duplicate. + if (field->type != GRPC_JSON_ARRAY) return nullptr; + // Find number of entries. + for (grpc_json* method = field->child; method != nullptr; + method = method->next) { + size_t count = CountNamesInMethodConfig(method); + if (count <= 0) return nullptr; + num_entries += count; + } + // Populate method config table entries. + entries = static_cast<typename SliceHashTable<RefCountedPtr<T>>::Entry*>( + gpr_zalloc(num_entries * + sizeof(typename SliceHashTable<RefCountedPtr<T>>::Entry))); + size_t idx = 0; + for (grpc_json* method = field->child; method != nullptr; + method = method->next) { + if (!ParseJsonMethodConfig(method, create_value, entries, &idx)) { + for (size_t i = 0; i < idx; ++i) { + grpc_slice_unref_internal(entries[i].key); + entries[i].value.reset(); + } + gpr_free(entries); + return nullptr; + } + } + GPR_ASSERT(idx == num_entries); + } + } + // Instantiate method config table. + RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> method_config_table; + if (entries != nullptr) { + method_config_table = + SliceHashTable<RefCountedPtr<T>>::Create(num_entries, entries, nullptr); + gpr_free(entries); + } + return method_config_table; +} + +template <typename T> +RefCountedPtr<T> ServiceConfig::MethodConfigTableLookup( + const SliceHashTable<RefCountedPtr<T>>& table, grpc_slice path) { + const RefCountedPtr<T>* value = table.Get(path); + // If we didn't find a match for the path, try looking for a wildcard + // entry (i.e., change "/service/method" to "/service/*"). + if (value == nullptr) { + char* path_str = grpc_slice_to_c_string(path); + const char* sep = strrchr(path_str, '/') + 1; + const size_t len = (size_t)(sep - path_str); + char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL + memcpy(buf, path_str, len); + buf[len] = '*'; + buf[len + 1] = '\0'; + grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); + gpr_free(buf); + value = table.Get(wildcard_path); + grpc_slice_unref_internal(wildcard_path); + gpr_free(path_str); + } + return RefCountedPtr<T>(*value); +} + +} // namespace grpc_core #endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */ diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 0e11b6e4e4..6a5144f21a 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -50,61 +50,64 @@ static uint8_t g_bytes[] = { 114, 110, 97, 108, 45, 115, 116, 114, 101, 97, 109, 45, 101, 110, 99, 111, 100, 105, 110, 103, 45, 114, 101, 113, 117, 101, 115, 116, 117, 115, 101, 114, 45, 97, 103, 101, 110, 116, 104, 111, 115, 116, 108, 98, 45, - 116, 111, 107, 101, 110, 103, 114, 112, 99, 45, 116, 105, 109, 101, 111, - 117, 116, 103, 114, 112, 99, 46, 119, 97, 105, 116, 95, 102, 111, 114, - 95, 114, 101, 97, 100, 121, 103, 114, 112, 99, 46, 116, 105, 109, 101, - 111, 117, 116, 103, 114, 112, 99, 46, 109, 97, 120, 95, 114, 101, 113, - 117, 101, 115, 116, 95, 109, 101, 115, 115, 97, 103, 101, 95, 98, 121, - 116, 101, 115, 103, 114, 112, 99, 46, 109, 97, 120, 95, 114, 101, 115, - 112, 111, 110, 115, 101, 95, 109, 101, 115, 115, 97, 103, 101, 95, 98, - 121, 116, 101, 115, 47, 103, 114, 112, 99, 46, 108, 98, 46, 118, 49, - 46, 76, 111, 97, 100, 66, 97, 108, 97, 110, 99, 101, 114, 47, 66, - 97, 108, 97, 110, 99, 101, 76, 111, 97, 100, 100, 101, 102, 108, 97, - 116, 101, 103, 122, 105, 112, 115, 116, 114, 101, 97, 109, 47, 103, 122, - 105, 112, 48, 49, 50, 105, 100, 101, 110, 116, 105, 116, 121, 116, 114, - 97, 105, 108, 101, 114, 115, 97, 112, 112, 108, 105, 99, 97, 116, 105, - 111, 110, 47, 103, 114, 112, 99, 80, 79, 83, 84, 50, 48, 48, 52, - 48, 52, 104, 116, 116, 112, 104, 116, 116, 112, 115, 103, 114, 112, 99, - 71, 69, 84, 80, 85, 84, 47, 47, 105, 110, 100, 101, 120, 46, 104, - 116, 109, 108, 50, 48, 52, 50, 48, 54, 51, 48, 52, 52, 48, 48, - 53, 48, 48, 97, 99, 99, 101, 112, 116, 45, 99, 104, 97, 114, 115, - 101, 116, 103, 122, 105, 112, 44, 32, 100, 101, 102, 108, 97, 116, 101, - 97, 99, 99, 101, 112, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, - 97, 99, 99, 101, 112, 116, 45, 114, 97, 110, 103, 101, 115, 97, 99, - 99, 101, 112, 116, 97, 99, 99, 101, 115, 115, 45, 99, 111, 110, 116, - 114, 111, 108, 45, 97, 108, 108, 111, 119, 45, 111, 114, 105, 103, 105, - 110, 97, 103, 101, 97, 108, 108, 111, 119, 97, 117, 116, 104, 111, 114, - 105, 122, 97, 116, 105, 111, 110, 99, 97, 99, 104, 101, 45, 99, 111, - 110, 116, 114, 111, 108, 99, 111, 110, 116, 101, 110, 116, 45, 100, 105, - 115, 112, 111, 115, 105, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, - 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 99, 111, 110, 116, 101, - 110, 116, 45, 108, 101, 110, 103, 116, 104, 99, 111, 110, 116, 101, 110, - 116, 45, 108, 111, 99, 97, 116, 105, 111, 110, 99, 111, 110, 116, 101, - 110, 116, 45, 114, 97, 110, 103, 101, 99, 111, 111, 107, 105, 101, 100, - 97, 116, 101, 101, 116, 97, 103, 101, 120, 112, 101, 99, 116, 101, 120, - 112, 105, 114, 101, 115, 102, 114, 111, 109, 105, 102, 45, 109, 97, 116, - 99, 104, 105, 102, 45, 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, - 105, 110, 99, 101, 105, 102, 45, 110, 111, 110, 101, 45, 109, 97, 116, - 99, 104, 105, 102, 45, 114, 97, 110, 103, 101, 105, 102, 45, 117, 110, - 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 108, - 97, 115, 116, 45, 109, 111, 100, 105, 102, 105, 101, 100, 108, 98, 45, - 99, 111, 115, 116, 45, 98, 105, 110, 108, 105, 110, 107, 108, 111, 99, - 97, 116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, - 100, 115, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, - 105, 99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, - 111, 114, 105, 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, - 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, - 116, 114, 121, 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, - 115, 101, 116, 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, - 116, 45, 116, 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, - 117, 114, 105, 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, - 110, 99, 111, 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, - 119, 119, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, - 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, - 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, 105, 112, 100, - 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105, 100, 101, 110, - 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, - 105, 112}; + 116, 111, 107, 101, 110, 103, 114, 112, 99, 45, 112, 114, 101, 118, 105, + 111, 117, 115, 45, 114, 112, 99, 45, 97, 116, 116, 101, 109, 112, 116, + 115, 103, 114, 112, 99, 45, 114, 101, 116, 114, 121, 45, 112, 117, 115, + 104, 98, 97, 99, 107, 45, 109, 115, 103, 114, 112, 99, 45, 116, 105, + 109, 101, 111, 117, 116, 49, 50, 51, 52, 103, 114, 112, 99, 46, 119, + 97, 105, 116, 95, 102, 111, 114, 95, 114, 101, 97, 100, 121, 103, 114, + 112, 99, 46, 116, 105, 109, 101, 111, 117, 116, 103, 114, 112, 99, 46, + 109, 97, 120, 95, 114, 101, 113, 117, 101, 115, 116, 95, 109, 101, 115, + 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 103, 114, 112, 99, 46, + 109, 97, 120, 95, 114, 101, 115, 112, 111, 110, 115, 101, 95, 109, 101, + 115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 47, 103, 114, 112, + 99, 46, 108, 98, 46, 118, 49, 46, 76, 111, 97, 100, 66, 97, 108, + 97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111, + 97, 100, 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, + 114, 101, 97, 109, 47, 103, 122, 105, 112, 48, 105, 100, 101, 110, 116, + 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, 115, 97, 112, 112, 108, + 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99, 80, 79, 83, + 84, 50, 48, 48, 52, 48, 52, 104, 116, 116, 112, 104, 116, 116, 112, + 115, 103, 114, 112, 99, 71, 69, 84, 80, 85, 84, 47, 47, 105, 110, + 100, 101, 120, 46, 104, 116, 109, 108, 50, 48, 52, 50, 48, 54, 51, + 48, 52, 52, 48, 48, 53, 48, 48, 97, 99, 99, 101, 112, 116, 45, + 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44, 32, 100, 101, + 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45, 108, 97, 110, + 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45, 114, 97, 110, + 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99, 101, 115, 115, + 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108, 111, 119, 45, + 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108, 111, 119, 97, + 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 99, 97, 99, + 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, 110, 116, 101, + 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 99, + 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, + 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 99, + 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, 105, 111, 110, + 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, 101, 99, 111, + 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, 97, 103, 101, 120, 112, + 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114, 111, 109, 105, + 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, 100, 105, 102, + 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45, 110, 111, 110, + 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97, 110, 103, 101, + 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, + 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100, 105, 102, 105, + 101, 100, 108, 98, 45, 99, 111, 115, 116, 45, 98, 105, 110, 108, 105, + 110, 107, 108, 111, 99, 97, 116, 105, 111, 110, 109, 97, 120, 45, 102, + 111, 114, 119, 97, 114, 100, 115, 112, 114, 111, 120, 121, 45, 97, 117, + 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 112, 114, 111, 120, 121, + 45, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 114, + 97, 110, 103, 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, + 101, 115, 104, 114, 101, 116, 114, 121, 45, 97, 102, 116, 101, 114, 115, + 101, 114, 118, 101, 114, 115, 101, 116, 45, 99, 111, 111, 107, 105, 101, + 115, 116, 114, 105, 99, 116, 45, 116, 114, 97, 110, 115, 112, 111, 114, + 116, 45, 115, 101, 99, 117, 114, 105, 116, 121, 116, 114, 97, 110, 115, + 102, 101, 114, 45, 101, 110, 99, 111, 100, 105, 110, 103, 118, 97, 114, + 121, 118, 105, 97, 119, 119, 119, 45, 97, 117, 116, 104, 101, 110, 116, + 105, 99, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, + 101, 102, 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, + 103, 122, 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, + 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, + 116, 101, 44, 103, 122, 105, 112}; static void static_ref(void* unused) {} static void static_unref(void* unused) {} @@ -217,6 +220,10 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_vtable, &static_sub_refcnt}, {&grpc_static_metadata_vtable, &static_sub_refcnt}, {&grpc_static_metadata_vtable, &static_sub_refcnt}, + {&grpc_static_metadata_vtable, &static_sub_refcnt}, + {&grpc_static_metadata_vtable, &static_sub_refcnt}, + {&grpc_static_metadata_vtable, &static_sub_refcnt}, + {&grpc_static_metadata_vtable, &static_sub_refcnt}, }; const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { @@ -242,85 +249,89 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, {&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}}, {&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, - {&grpc_static_metadata_refcounts[22], {{g_bytes + 290, 12}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}, - {&grpc_static_metadata_refcounts[24], {{g_bytes + 302, 19}}}, - {&grpc_static_metadata_refcounts[25], {{g_bytes + 321, 12}}}, - {&grpc_static_metadata_refcounts[26], {{g_bytes + 333, 30}}}, - {&grpc_static_metadata_refcounts[27], {{g_bytes + 363, 31}}}, - {&grpc_static_metadata_refcounts[28], {{g_bytes + 394, 36}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 430, 7}}}, - {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}}, - {&grpc_static_metadata_refcounts[31], {{g_bytes + 441, 11}}}, - {&grpc_static_metadata_refcounts[32], {{g_bytes + 452, 1}}}, - {&grpc_static_metadata_refcounts[33], {{g_bytes + 453, 1}}}, - {&grpc_static_metadata_refcounts[34], {{g_bytes + 454, 1}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 463, 8}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 471, 16}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 487, 4}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 491, 3}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 494, 3}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 497, 4}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 501, 5}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 506, 4}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 510, 3}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 513, 3}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 516, 1}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 517, 11}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 528, 3}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 531, 3}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 534, 3}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 537, 3}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 540, 3}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 543, 14}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 557, 13}}}, - {&grpc_static_metadata_refcounts[55], {{g_bytes + 570, 15}}}, - {&grpc_static_metadata_refcounts[56], {{g_bytes + 585, 13}}}, - {&grpc_static_metadata_refcounts[57], {{g_bytes + 598, 6}}}, - {&grpc_static_metadata_refcounts[58], {{g_bytes + 604, 27}}}, - {&grpc_static_metadata_refcounts[59], {{g_bytes + 631, 3}}}, - {&grpc_static_metadata_refcounts[60], {{g_bytes + 634, 5}}}, - {&grpc_static_metadata_refcounts[61], {{g_bytes + 639, 13}}}, - {&grpc_static_metadata_refcounts[62], {{g_bytes + 652, 13}}}, - {&grpc_static_metadata_refcounts[63], {{g_bytes + 665, 19}}}, - {&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 16}}}, - {&grpc_static_metadata_refcounts[65], {{g_bytes + 700, 14}}}, - {&grpc_static_metadata_refcounts[66], {{g_bytes + 714, 16}}}, - {&grpc_static_metadata_refcounts[67], {{g_bytes + 730, 13}}}, - {&grpc_static_metadata_refcounts[68], {{g_bytes + 743, 6}}}, - {&grpc_static_metadata_refcounts[69], {{g_bytes + 749, 4}}}, - {&grpc_static_metadata_refcounts[70], {{g_bytes + 753, 4}}}, - {&grpc_static_metadata_refcounts[71], {{g_bytes + 757, 6}}}, - {&grpc_static_metadata_refcounts[72], {{g_bytes + 763, 7}}}, - {&grpc_static_metadata_refcounts[73], {{g_bytes + 770, 4}}}, - {&grpc_static_metadata_refcounts[74], {{g_bytes + 774, 8}}}, - {&grpc_static_metadata_refcounts[75], {{g_bytes + 782, 17}}}, - {&grpc_static_metadata_refcounts[76], {{g_bytes + 799, 13}}}, - {&grpc_static_metadata_refcounts[77], {{g_bytes + 812, 8}}}, - {&grpc_static_metadata_refcounts[78], {{g_bytes + 820, 19}}}, - {&grpc_static_metadata_refcounts[79], {{g_bytes + 839, 13}}}, - {&grpc_static_metadata_refcounts[80], {{g_bytes + 852, 11}}}, - {&grpc_static_metadata_refcounts[81], {{g_bytes + 863, 4}}}, - {&grpc_static_metadata_refcounts[82], {{g_bytes + 867, 8}}}, - {&grpc_static_metadata_refcounts[83], {{g_bytes + 875, 12}}}, - {&grpc_static_metadata_refcounts[84], {{g_bytes + 887, 18}}}, - {&grpc_static_metadata_refcounts[85], {{g_bytes + 905, 19}}}, - {&grpc_static_metadata_refcounts[86], {{g_bytes + 924, 5}}}, - {&grpc_static_metadata_refcounts[87], {{g_bytes + 929, 7}}}, - {&grpc_static_metadata_refcounts[88], {{g_bytes + 936, 7}}}, - {&grpc_static_metadata_refcounts[89], {{g_bytes + 943, 11}}}, - {&grpc_static_metadata_refcounts[90], {{g_bytes + 954, 6}}}, - {&grpc_static_metadata_refcounts[91], {{g_bytes + 960, 10}}}, - {&grpc_static_metadata_refcounts[92], {{g_bytes + 970, 25}}}, - {&grpc_static_metadata_refcounts[93], {{g_bytes + 995, 17}}}, - {&grpc_static_metadata_refcounts[94], {{g_bytes + 1012, 4}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1016, 3}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1019, 16}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1035, 16}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1051, 13}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1064, 12}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1076, 21}}}, + {&grpc_static_metadata_refcounts[22], {{g_bytes + 290, 26}}}, + {&grpc_static_metadata_refcounts[23], {{g_bytes + 316, 22}}}, + {&grpc_static_metadata_refcounts[24], {{g_bytes + 338, 12}}}, + {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}, + {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}, + {&grpc_static_metadata_refcounts[27], {{g_bytes + 352, 1}}}, + {&grpc_static_metadata_refcounts[28], {{g_bytes + 353, 1}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}, + {&grpc_static_metadata_refcounts[30], {{g_bytes + 354, 19}}}, + {&grpc_static_metadata_refcounts[31], {{g_bytes + 373, 12}}}, + {&grpc_static_metadata_refcounts[32], {{g_bytes + 385, 30}}}, + {&grpc_static_metadata_refcounts[33], {{g_bytes + 415, 31}}}, + {&grpc_static_metadata_refcounts[34], {{g_bytes + 446, 36}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 493, 11}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 1}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 513, 8}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 521, 16}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 537, 4}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 541, 3}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 544, 3}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 547, 4}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 551, 5}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 556, 4}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 560, 3}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 563, 3}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 566, 1}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 567, 11}}}, + {&grpc_static_metadata_refcounts[52], {{g_bytes + 578, 3}}}, + {&grpc_static_metadata_refcounts[53], {{g_bytes + 581, 3}}}, + {&grpc_static_metadata_refcounts[54], {{g_bytes + 584, 3}}}, + {&grpc_static_metadata_refcounts[55], {{g_bytes + 587, 3}}}, + {&grpc_static_metadata_refcounts[56], {{g_bytes + 590, 3}}}, + {&grpc_static_metadata_refcounts[57], {{g_bytes + 593, 14}}}, + {&grpc_static_metadata_refcounts[58], {{g_bytes + 607, 13}}}, + {&grpc_static_metadata_refcounts[59], {{g_bytes + 620, 15}}}, + {&grpc_static_metadata_refcounts[60], {{g_bytes + 635, 13}}}, + {&grpc_static_metadata_refcounts[61], {{g_bytes + 648, 6}}}, + {&grpc_static_metadata_refcounts[62], {{g_bytes + 654, 27}}}, + {&grpc_static_metadata_refcounts[63], {{g_bytes + 681, 3}}}, + {&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 5}}}, + {&grpc_static_metadata_refcounts[65], {{g_bytes + 689, 13}}}, + {&grpc_static_metadata_refcounts[66], {{g_bytes + 702, 13}}}, + {&grpc_static_metadata_refcounts[67], {{g_bytes + 715, 19}}}, + {&grpc_static_metadata_refcounts[68], {{g_bytes + 734, 16}}}, + {&grpc_static_metadata_refcounts[69], {{g_bytes + 750, 14}}}, + {&grpc_static_metadata_refcounts[70], {{g_bytes + 764, 16}}}, + {&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 13}}}, + {&grpc_static_metadata_refcounts[72], {{g_bytes + 793, 6}}}, + {&grpc_static_metadata_refcounts[73], {{g_bytes + 799, 4}}}, + {&grpc_static_metadata_refcounts[74], {{g_bytes + 803, 4}}}, + {&grpc_static_metadata_refcounts[75], {{g_bytes + 807, 6}}}, + {&grpc_static_metadata_refcounts[76], {{g_bytes + 813, 7}}}, + {&grpc_static_metadata_refcounts[77], {{g_bytes + 820, 4}}}, + {&grpc_static_metadata_refcounts[78], {{g_bytes + 824, 8}}}, + {&grpc_static_metadata_refcounts[79], {{g_bytes + 832, 17}}}, + {&grpc_static_metadata_refcounts[80], {{g_bytes + 849, 13}}}, + {&grpc_static_metadata_refcounts[81], {{g_bytes + 862, 8}}}, + {&grpc_static_metadata_refcounts[82], {{g_bytes + 870, 19}}}, + {&grpc_static_metadata_refcounts[83], {{g_bytes + 889, 13}}}, + {&grpc_static_metadata_refcounts[84], {{g_bytes + 902, 11}}}, + {&grpc_static_metadata_refcounts[85], {{g_bytes + 913, 4}}}, + {&grpc_static_metadata_refcounts[86], {{g_bytes + 917, 8}}}, + {&grpc_static_metadata_refcounts[87], {{g_bytes + 925, 12}}}, + {&grpc_static_metadata_refcounts[88], {{g_bytes + 937, 18}}}, + {&grpc_static_metadata_refcounts[89], {{g_bytes + 955, 19}}}, + {&grpc_static_metadata_refcounts[90], {{g_bytes + 974, 5}}}, + {&grpc_static_metadata_refcounts[91], {{g_bytes + 979, 7}}}, + {&grpc_static_metadata_refcounts[92], {{g_bytes + 986, 7}}}, + {&grpc_static_metadata_refcounts[93], {{g_bytes + 993, 11}}}, + {&grpc_static_metadata_refcounts[94], {{g_bytes + 1004, 6}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1010, 10}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1020, 25}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1045, 17}}}, + {&grpc_static_metadata_refcounts[98], {{g_bytes + 1062, 4}}}, + {&grpc_static_metadata_refcounts[99], {{g_bytes + 1066, 3}}}, + {&grpc_static_metadata_refcounts[100], {{g_bytes + 1069, 16}}}, + {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}, }; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { @@ -330,50 +341,51 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4}; static const int8_t elems_r[] = { - 13, 2, 1, 0, 15, 4, 0, 21, 0, 23, -3, 0, 0, 0, 10, 19, -4, - 0, 0, 1, 10, 9, 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, -52, 0, -55, -36, -57, -58, -58, -58, 0, 40, 39, 38, 37, 36, 35, - 34, 33, 32, 31, 30, 29, 28, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, - 18, 17, 16, 15, 18, 17, 16, 15, 14, 13, 12, 11, 11, 0}; + 16, 11, -1, 0, 15, 2, -78, 24, 0, 18, -5, 0, 0, 0, 17, 14, -8, 0, + 0, 27, 8, 7, 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, -64, 0, -44, -43, -70, 0, 34, 33, 33, 32, 31, 30, 29, 28, 27, + 27, 26, 25, 24, 23, 22, 21, 20, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, + 11, 14, 13, 12, 11, 10, 9, 9, 8, 7, 6, 5, 0}; static uint32_t elems_phash(uint32_t i) { - i -= 46; - uint32_t x = i % 99; - uint32_t y = i / 99; + i -= 50; + uint32_t x = i % 103; + uint32_t y = i / 103; uint32_t h = x; if (y < GPR_ARRAY_SIZE(elems_r)) { - uint32_t delta = static_cast<uint32_t>(elems_r[y]); + uint32_t delta = (uint32_t)elems_r[y]; h += delta; } return h; } static const uint16_t elem_keys[] = { - 1039, 1040, 145, 146, 541, 1639, 1045, 250, 251, 252, 253, 254, - 1646, 46, 47, 1437, 1942, 1651, 445, 446, 447, 739, 740, 741, - 938, 939, 1538, 2043, 2144, 1451, 944, 5376, 5578, 1545, 5780, 5881, - 1670, 5982, 1550, 6083, 6184, 6285, 6386, 6487, 6588, 6689, 6790, 6891, - 6992, 7093, 7194, 7295, 7396, 5679, 7497, 7598, 7699, 7800, 7901, 8002, - 8103, 8204, 8305, 8406, 8507, 8608, 8709, 8810, 1107, 1108, 1109, 1110, - 8911, 9012, 9113, 9214, 9315, 9416, 9517, 9618, 1714, 9719, 0, 326, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 241, 242, 0, 0, 0, 0, 0, 0, 139, 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}; + 1085, 1086, 565, 1709, 1089, 262, 263, 264, 265, 266, 1716, + 153, 154, 1719, 760, 761, 50, 51, 465, 466, 467, 980, + 981, 1604, 1499, 984, 773, 2129, 2234, 6014, 1611, 6434, 1738, + 1614, 6539, 6644, 1511, 6749, 6854, 6959, 7064, 7169, 7274, 7379, + 2024, 7484, 7589, 7694, 7799, 7904, 8009, 8114, 8219, 6224, 8324, + 8429, 6329, 8534, 8639, 8744, 8849, 8954, 9059, 9164, 9269, 9374, + 1151, 1152, 1153, 1154, 9479, 9584, 9689, 9794, 9899, 10004, 1782, + 10109, 10214, 10319, 10424, 10529, 0, 0, 0, 0, 0, 344, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 253, 254, 147, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; static const uint8_t elem_idxs[] = { - 77, 79, 15, 16, 6, 25, 76, 19, 20, 21, 22, 23, 84, 17, - 18, 43, 72, 83, 11, 12, 13, 0, 1, 2, 5, 4, 38, 50, - 57, 7, 3, 24, 27, 37, 29, 30, 26, 31, 36, 32, 33, 34, - 35, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 28, 51, 52, - 53, 54, 55, 56, 58, 59, 60, 61, 62, 63, 64, 65, 78, 80, - 81, 82, 66, 67, 68, 69, 70, 71, 73, 74, 85, 75, 255, 14, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 9, 10, 255, 255, 255, 255, 255, 255, 8}; + 77, 79, 6, 25, 76, 19, 20, 21, 22, 23, 84, 15, 16, 83, 1, + 2, 17, 18, 11, 12, 13, 5, 4, 38, 43, 3, 0, 50, 57, 24, + 37, 29, 26, 36, 30, 31, 7, 32, 33, 34, 35, 39, 40, 41, 72, + 42, 44, 45, 46, 47, 48, 49, 51, 27, 52, 53, 28, 54, 55, 56, + 58, 59, 60, 61, 62, 63, 78, 80, 81, 82, 64, 65, 66, 67, 68, + 69, 85, 70, 71, 73, 74, 75, 255, 255, 255, 255, 255, 14, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 9, 10, 8}; grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { if (a == -1 || b == -1) return GRPC_MDNULL; - uint32_t k = static_cast<uint32_t>(a * 101 + b); + uint32_t k = (uint32_t)(a * 105 + b); uint32_t h = elems_phash(k); return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 @@ -384,177 +396,177 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[32], {{g_bytes + 452, 1}}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 1}}}}, {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[33], {{g_bytes + 453, 1}}}}, + {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[34], {{g_bytes + 454, 1}}}}, + {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 430, 7}}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 463, 8}}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 513, 8}}}}, {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 471, 16}}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 521, 16}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 487, 4}}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 537, 4}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 491, 3}}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 541, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 494, 3}}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 544, 3}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 497, 4}}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 547, 4}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 501, 5}}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 551, 5}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 506, 4}}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 556, 4}}}}, {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 510, 3}}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 560, 3}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 513, 3}}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 563, 3}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 516, 1}}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 566, 1}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 517, 11}}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 567, 11}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 528, 3}}}}, + {&grpc_static_metadata_refcounts[52], {{g_bytes + 578, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 531, 3}}}}, + {&grpc_static_metadata_refcounts[53], {{g_bytes + 581, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 534, 3}}}}, + {&grpc_static_metadata_refcounts[54], {{g_bytes + 584, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 537, 3}}}}, + {&grpc_static_metadata_refcounts[55], {{g_bytes + 587, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 540, 3}}}}, - {{&grpc_static_metadata_refcounts[53], {{g_bytes + 543, 14}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, + {&grpc_static_metadata_refcounts[56], {{g_bytes + 590, 3}}}}, + {{&grpc_static_metadata_refcounts[57], {{g_bytes + 593, 14}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 557, 13}}}}, - {{&grpc_static_metadata_refcounts[55], {{g_bytes + 570, 15}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[56], {{g_bytes + 585, 13}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[57], {{g_bytes + 598, 6}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[58], {{g_bytes + 604, 27}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[59], {{g_bytes + 631, 3}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[60], {{g_bytes + 634, 5}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[61], {{g_bytes + 639, 13}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[62], {{g_bytes + 652, 13}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[63], {{g_bytes + 665, 19}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, + {&grpc_static_metadata_refcounts[58], {{g_bytes + 607, 13}}}}, + {{&grpc_static_metadata_refcounts[59], {{g_bytes + 620, 15}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[60], {{g_bytes + 635, 13}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[61], {{g_bytes + 648, 6}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[62], {{g_bytes + 654, 27}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[63], {{g_bytes + 681, 3}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 5}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[65], {{g_bytes + 689, 13}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[66], {{g_bytes + 702, 13}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[67], {{g_bytes + 715, 19}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 16}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[65], {{g_bytes + 700, 14}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[66], {{g_bytes + 714, 16}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[67], {{g_bytes + 730, 13}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[68], {{g_bytes + 734, 16}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[69], {{g_bytes + 750, 14}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[70], {{g_bytes + 764, 16}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 13}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[68], {{g_bytes + 743, 6}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[69], {{g_bytes + 749, 4}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[70], {{g_bytes + 753, 4}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[71], {{g_bytes + 757, 6}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[72], {{g_bytes + 763, 7}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[73], {{g_bytes + 770, 4}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[72], {{g_bytes + 793, 6}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[73], {{g_bytes + 799, 4}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[74], {{g_bytes + 803, 4}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[75], {{g_bytes + 807, 6}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[76], {{g_bytes + 813, 7}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[77], {{g_bytes + 820, 4}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[74], {{g_bytes + 774, 8}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[75], {{g_bytes + 782, 17}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[76], {{g_bytes + 799, 13}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[77], {{g_bytes + 812, 8}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[78], {{g_bytes + 820, 19}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[79], {{g_bytes + 839, 13}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[78], {{g_bytes + 824, 8}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[79], {{g_bytes + 832, 17}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[80], {{g_bytes + 849, 13}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[81], {{g_bytes + 862, 8}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[82], {{g_bytes + 870, 19}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[83], {{g_bytes + 889, 13}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[80], {{g_bytes + 852, 11}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[81], {{g_bytes + 863, 4}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[82], {{g_bytes + 867, 8}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[83], {{g_bytes + 875, 12}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[84], {{g_bytes + 887, 18}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[85], {{g_bytes + 905, 19}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[86], {{g_bytes + 924, 5}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[87], {{g_bytes + 929, 7}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[88], {{g_bytes + 936, 7}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[89], {{g_bytes + 943, 11}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[90], {{g_bytes + 954, 6}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[91], {{g_bytes + 960, 10}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[92], {{g_bytes + 970, 25}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[93], {{g_bytes + 995, 17}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[84], {{g_bytes + 902, 11}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[85], {{g_bytes + 913, 4}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[86], {{g_bytes + 917, 8}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[87], {{g_bytes + 925, 12}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[88], {{g_bytes + 937, 18}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[89], {{g_bytes + 955, 19}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[90], {{g_bytes + 974, 5}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[91], {{g_bytes + 979, 7}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[92], {{g_bytes + 986, 7}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[93], {{g_bytes + 993, 11}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1004, 6}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1010, 10}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[96], {{g_bytes + 1020, 25}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[97], {{g_bytes + 1045, 17}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1012, 4}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1016, 3}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, - {{&grpc_static_metadata_refcounts[96], {{g_bytes + 1019, 16}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[98], {{g_bytes + 1062, 4}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[99], {{g_bytes + 1066, 3}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[100], {{g_bytes + 1069, 16}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 430, 7}}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1035, 16}}}}, + {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1051, 13}}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1064, 12}}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1076, 21}}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1051, 13}}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, }; bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = { true, // :path @@ -579,6 +591,8 @@ bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = { true, // user-agent true, // host true, // lb-token + true, // grpc-previous-rpc-attempts + true, // grpc-retry-pushback-ms }; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 88d9f9f52c..b3a10f5873 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -31,7 +31,7 @@ #include "src/core/lib/transport/metadata.h" -#define GRPC_STATIC_MDSTR_COUNT 101 +#define GRPC_STATIC_MDSTR_COUNT 105 extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* ":path" */ #define GRPC_MDSTR_PATH (grpc_static_slice_table[0]) @@ -78,168 +78,176 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_MDSTR_HOST (grpc_static_slice_table[20]) /* "lb-token" */ #define GRPC_MDSTR_LB_TOKEN (grpc_static_slice_table[21]) +/* "grpc-previous-rpc-attempts" */ +#define GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS (grpc_static_slice_table[22]) +/* "grpc-retry-pushback-ms" */ +#define GRPC_MDSTR_GRPC_RETRY_PUSHBACK_MS (grpc_static_slice_table[23]) /* "grpc-timeout" */ -#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[22]) +#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[24]) +/* "1" */ +#define GRPC_MDSTR_1 (grpc_static_slice_table[25]) +/* "2" */ +#define GRPC_MDSTR_2 (grpc_static_slice_table[26]) +/* "3" */ +#define GRPC_MDSTR_3 (grpc_static_slice_table[27]) +/* "4" */ +#define GRPC_MDSTR_4 (grpc_static_slice_table[28]) /* "" */ -#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[23]) +#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[29]) /* "grpc.wait_for_ready" */ -#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[24]) +#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[30]) /* "grpc.timeout" */ -#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[25]) +#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[31]) /* "grpc.max_request_message_bytes" */ #define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES \ - (grpc_static_slice_table[26]) + (grpc_static_slice_table[32]) /* "grpc.max_response_message_bytes" */ #define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \ - (grpc_static_slice_table[27]) + (grpc_static_slice_table[33]) /* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */ #define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \ - (grpc_static_slice_table[28]) + (grpc_static_slice_table[34]) /* "deflate" */ -#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[29]) +#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35]) /* "gzip" */ -#define GRPC_MDSTR_GZIP (grpc_static_slice_table[30]) +#define GRPC_MDSTR_GZIP (grpc_static_slice_table[36]) /* "stream/gzip" */ -#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[31]) +#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[37]) /* "0" */ -#define GRPC_MDSTR_0 (grpc_static_slice_table[32]) -/* "1" */ -#define GRPC_MDSTR_1 (grpc_static_slice_table[33]) -/* "2" */ -#define GRPC_MDSTR_2 (grpc_static_slice_table[34]) +#define GRPC_MDSTR_0 (grpc_static_slice_table[38]) /* "identity" */ -#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[35]) +#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[39]) /* "trailers" */ -#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[36]) +#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[40]) /* "application/grpc" */ -#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[37]) +#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[41]) /* "POST" */ -#define GRPC_MDSTR_POST (grpc_static_slice_table[38]) +#define GRPC_MDSTR_POST (grpc_static_slice_table[42]) /* "200" */ -#define GRPC_MDSTR_200 (grpc_static_slice_table[39]) +#define GRPC_MDSTR_200 (grpc_static_slice_table[43]) /* "404" */ -#define GRPC_MDSTR_404 (grpc_static_slice_table[40]) +#define GRPC_MDSTR_404 (grpc_static_slice_table[44]) /* "http" */ -#define GRPC_MDSTR_HTTP (grpc_static_slice_table[41]) +#define GRPC_MDSTR_HTTP (grpc_static_slice_table[45]) /* "https" */ -#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[42]) +#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[46]) /* "grpc" */ -#define GRPC_MDSTR_GRPC (grpc_static_slice_table[43]) +#define GRPC_MDSTR_GRPC (grpc_static_slice_table[47]) /* "GET" */ -#define GRPC_MDSTR_GET (grpc_static_slice_table[44]) +#define GRPC_MDSTR_GET (grpc_static_slice_table[48]) /* "PUT" */ -#define GRPC_MDSTR_PUT (grpc_static_slice_table[45]) +#define GRPC_MDSTR_PUT (grpc_static_slice_table[49]) /* "/" */ -#define GRPC_MDSTR_SLASH (grpc_static_slice_table[46]) +#define GRPC_MDSTR_SLASH (grpc_static_slice_table[50]) /* "/index.html" */ -#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[47]) +#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[51]) /* "204" */ -#define GRPC_MDSTR_204 (grpc_static_slice_table[48]) +#define GRPC_MDSTR_204 (grpc_static_slice_table[52]) /* "206" */ -#define GRPC_MDSTR_206 (grpc_static_slice_table[49]) +#define GRPC_MDSTR_206 (grpc_static_slice_table[53]) /* "304" */ -#define GRPC_MDSTR_304 (grpc_static_slice_table[50]) +#define GRPC_MDSTR_304 (grpc_static_slice_table[54]) /* "400" */ -#define GRPC_MDSTR_400 (grpc_static_slice_table[51]) +#define GRPC_MDSTR_400 (grpc_static_slice_table[55]) /* "500" */ -#define GRPC_MDSTR_500 (grpc_static_slice_table[52]) +#define GRPC_MDSTR_500 (grpc_static_slice_table[56]) /* "accept-charset" */ -#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[53]) +#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[57]) /* "gzip, deflate" */ -#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[54]) +#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[58]) /* "accept-language" */ -#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[55]) +#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[59]) /* "accept-ranges" */ -#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[56]) +#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[60]) /* "accept" */ -#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[57]) +#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[61]) /* "access-control-allow-origin" */ -#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[58]) +#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[62]) /* "age" */ -#define GRPC_MDSTR_AGE (grpc_static_slice_table[59]) +#define GRPC_MDSTR_AGE (grpc_static_slice_table[63]) /* "allow" */ -#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[60]) +#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[64]) /* "authorization" */ -#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[61]) +#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[65]) /* "cache-control" */ -#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[62]) +#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[66]) /* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[63]) +#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[67]) /* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[64]) +#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[68]) /* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[65]) +#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[69]) /* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[66]) +#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[70]) /* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[67]) +#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[71]) /* "cookie" */ -#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[68]) +#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[72]) /* "date" */ -#define GRPC_MDSTR_DATE (grpc_static_slice_table[69]) +#define GRPC_MDSTR_DATE (grpc_static_slice_table[73]) /* "etag" */ -#define GRPC_MDSTR_ETAG (grpc_static_slice_table[70]) +#define GRPC_MDSTR_ETAG (grpc_static_slice_table[74]) /* "expect" */ -#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[71]) +#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[75]) /* "expires" */ -#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[72]) +#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[76]) /* "from" */ -#define GRPC_MDSTR_FROM (grpc_static_slice_table[73]) +#define GRPC_MDSTR_FROM (grpc_static_slice_table[77]) /* "if-match" */ -#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[74]) +#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[78]) /* "if-modified-since" */ -#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[75]) +#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[79]) /* "if-none-match" */ -#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[76]) +#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[80]) /* "if-range" */ -#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[77]) +#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[81]) /* "if-unmodified-since" */ -#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[78]) +#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[82]) /* "last-modified" */ -#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[79]) +#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[83]) /* "lb-cost-bin" */ -#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[80]) +#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[84]) /* "link" */ -#define GRPC_MDSTR_LINK (grpc_static_slice_table[81]) +#define GRPC_MDSTR_LINK (grpc_static_slice_table[85]) /* "location" */ -#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[82]) +#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[86]) /* "max-forwards" */ -#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[83]) +#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[87]) /* "proxy-authenticate" */ -#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[84]) +#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[88]) /* "proxy-authorization" */ -#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[85]) +#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[89]) /* "range" */ -#define GRPC_MDSTR_RANGE (grpc_static_slice_table[86]) +#define GRPC_MDSTR_RANGE (grpc_static_slice_table[90]) /* "referer" */ -#define GRPC_MDSTR_REFERER (grpc_static_slice_table[87]) +#define GRPC_MDSTR_REFERER (grpc_static_slice_table[91]) /* "refresh" */ -#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[88]) +#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[92]) /* "retry-after" */ -#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[89]) +#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[93]) /* "server" */ -#define GRPC_MDSTR_SERVER (grpc_static_slice_table[90]) +#define GRPC_MDSTR_SERVER (grpc_static_slice_table[94]) /* "set-cookie" */ -#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[91]) +#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[95]) /* "strict-transport-security" */ -#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[92]) +#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[96]) /* "transfer-encoding" */ -#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[93]) +#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[97]) /* "vary" */ -#define GRPC_MDSTR_VARY (grpc_static_slice_table[94]) +#define GRPC_MDSTR_VARY (grpc_static_slice_table[98]) /* "via" */ -#define GRPC_MDSTR_VIA (grpc_static_slice_table[95]) +#define GRPC_MDSTR_VIA (grpc_static_slice_table[99]) /* "www-authenticate" */ -#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[96]) +#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[100]) /* "identity,deflate" */ -#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[97]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[101]) /* "identity,gzip" */ -#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[98]) +#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[102]) /* "deflate,gzip" */ -#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[99]) +#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[103]) /* "identity,deflate,gzip" */ #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (grpc_static_slice_table[100]) + (grpc_static_slice_table[104]) extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; extern grpc_slice_refcount @@ -537,6 +545,8 @@ typedef enum { GRPC_BATCH_USER_AGENT, GRPC_BATCH_HOST, GRPC_BATCH_LB_TOKEN, + GRPC_BATCH_GRPC_PREVIOUS_RPC_ATTEMPTS, + GRPC_BATCH_GRPC_RETRY_PUSHBACK_MS, GRPC_BATCH_CALLOUTS_COUNT } grpc_metadata_batch_callouts_index; @@ -565,6 +575,8 @@ typedef union { struct grpc_linked_mdelem* user_agent; struct grpc_linked_mdelem* host; struct grpc_linked_mdelem* lb_token; + struct grpc_linked_mdelem* grpc_previous_rpc_attempts; + struct grpc_linked_mdelem* grpc_retry_pushback_ms; } named; } grpc_metadata_batch_callouts; diff --git a/src/core/lib/transport/status_metadata.cc b/src/core/lib/transport/status_metadata.cc new file mode 100644 index 0000000000..f896053e4d --- /dev/null +++ b/src/core/lib/transport/status_metadata.cc @@ -0,0 +1,54 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/support/port_platform.h> + +#include "src/core/lib/transport/status_metadata.h" + +#include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/transport/static_metadata.h" + +/* we offset status by a small amount when storing it into transport metadata + as metadata cannot store a 0 value (which is used as OK for grpc_status_codes + */ +#define STATUS_OFFSET 1 + +static void destroy_status(void* ignored) {} + +grpc_status_code grpc_get_status_code_from_metadata(grpc_mdelem md) { + if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + return GRPC_STATUS_OK; + } + if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_1)) { + return GRPC_STATUS_CANCELLED; + } + if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_2)) { + return GRPC_STATUS_UNKNOWN; + } + void* user_data = grpc_mdelem_get_user_data(md, destroy_status); + if (user_data != nullptr) { + return static_cast<grpc_status_code>((intptr_t)user_data - STATUS_OFFSET); + } + uint32_t status; + if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(md), &status)) { + status = GRPC_STATUS_UNKNOWN; /* could not parse status code */ + } + grpc_mdelem_set_user_data( + md, destroy_status, (void*)static_cast<intptr_t>(status + STATUS_OFFSET)); + return static_cast<grpc_status_code>(status); +} diff --git a/src/core/lib/security/transport/lb_targets_info.h b/src/core/lib/transport/status_metadata.h index 7e816c5222..aed9c7ac20 100644 --- a/src/core/lib/security/transport/lb_targets_info.h +++ b/src/core/lib/transport/status_metadata.h @@ -16,19 +16,15 @@ * */ -#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H -#define GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H +#ifndef GRPC_CORE_LIB_TRANSPORT_STATUS_METADATA_H +#define GRPC_CORE_LIB_TRANSPORT_STATUS_METADATA_H #include <grpc/support/port_platform.h> -#include "src/core/lib/slice/slice_hash_table.h" +#include <grpc/status.h> -/** Return a channel argument containing \a targets_info. */ -grpc_arg grpc_lb_targets_info_create_channel_arg( - grpc_slice_hash_table* targets_info); +#include "src/core/lib/transport/metadata.h" -/** Return the instance of targets info in \a args or NULL */ -grpc_slice_hash_table* grpc_lb_targets_info_find_in_args( - const grpc_channel_args* args); +grpc_status_code grpc_get_status_code_from_metadata(grpc_mdelem md); -#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_STATUS_METADATA_H */ diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index b279ce8c80..37e50344c4 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -98,6 +98,19 @@ void grpc_transport_move_one_way_stats(grpc_transport_one_way_stats* from, void grpc_transport_move_stats(grpc_transport_stream_stats* from, grpc_transport_stream_stats* to); +// This struct (which is present in both grpc_transport_stream_op_batch +// and grpc_transport_op_batch) is a convenience to allow filters or +// transports to schedule a closure related to a particular batch without +// having to allocate memory. The general pattern is to initialize the +// closure with the callback arg set to the batch and extra_arg set to +// whatever state is associated with the handler (e.g., the call element +// or the transport stream object). +// +// Note that this can only be used by the current handler of a given +// batch on the way down the stack (i.e., whichever filter or transport is +// currently handling the batch). Once a filter or transport passes control +// of the batch to the next handler, it cannot depend on the contents of +// this struct anymore, because the next handler may reuse it. typedef struct { void* extra_arg; grpc_closure closure; @@ -157,6 +170,11 @@ struct grpc_transport_stream_op_batch_payload { uint32_t send_initial_metadata_flags; // If non-NULL, will be set by the transport to the peer string // (a char*, which the caller takes ownership of). + // Note: This pointer may be used by the transport after the + // send_initial_metadata op is completed. It must remain valid + // until the call is destroyed. + // Note: When a transport sets this, it must free the previous + // value, if any. gpr_atm* peer_string; } send_initial_metadata; @@ -175,6 +193,9 @@ struct grpc_transport_stream_op_batch_payload { struct { grpc_metadata_batch* recv_initial_metadata; + // Flags are used only on the server side. If non-null, will be set to + // a bitfield of the GRPC_INITIAL_METADATA_xxx macros (e.g., to + // indicate if the call is idempotent). uint32_t* recv_flags; /** Should be enqueued when initial metadata is ready to be processed. */ grpc_closure* recv_initial_metadata_ready; @@ -184,6 +205,11 @@ struct grpc_transport_stream_op_batch_payload { bool* trailing_metadata_available; // If non-NULL, will be set by the transport to the peer string // (a char*, which the caller takes ownership of). + // Note: This pointer may be used by the transport after the + // recv_initial_metadata op is completed. It must remain valid + // until the call is destroyed. + // Note: When a transport sets this, it must free the previous + // value, if any. gpr_atm* peer_string; } recv_initial_metadata; @@ -192,6 +218,7 @@ struct grpc_transport_stream_op_batch_payload { // containing a received message. // The caller is responsible for calling grpc_byte_stream_destroy() // on this byte stream. + // Will be NULL if trailing metadata is received instead of a message. grpc_byte_stream** recv_message; /** Should be enqueued when one message is ready to be processed. */ grpc_closure* recv_message_ready; |