grpc 1.21.0 → 1.22.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +422 -62
- data/include/grpc/grpc_security.h +61 -5
- data/include/grpc/grpc_security_constants.h +1 -1
- data/include/grpc/impl/codegen/gpr_types.h +1 -1
- data/include/grpc/slice.h +2 -2
- data/src/core/ext/filters/client_channel/backup_poller.cc +2 -3
- data/src/core/ext/filters/client_channel/backup_poller.h +5 -2
- data/src/core/ext/filters/client_channel/client_channel.cc +260 -122
- data/src/core/ext/filters/client_channel/client_channel.h +0 -8
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +3 -84
- data/src/core/ext/filters/client_channel/client_channel_channelz.h +2 -28
- data/src/core/ext/filters/client_channel/client_channel_plugin.cc +2 -8
- data/src/core/ext/filters/client_channel/health/health_check_client.cc +5 -4
- data/src/core/ext/filters/client_channel/lb_policy.cc +16 -2
- data/src/core/ext/filters/client_channel/lb_policy.h +92 -98
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +63 -87
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +6 -2
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +35 -87
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +18 -74
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +167 -217
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +216 -190
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +6 -2
- data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -1
- data/src/core/ext/filters/client_channel/lb_policy_registry.cc +1 -1
- data/src/core/ext/filters/client_channel/lb_policy_registry.h +1 -1
- data/src/core/ext/filters/client_channel/resolver.h +1 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +6 -3
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +0 -1
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -0
- data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +8 -8
- data/src/core/ext/filters/client_channel/resolver_result_parsing.h +7 -7
- data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +28 -64
- data/src/core/ext/filters/client_channel/resolving_lb_policy.h +4 -12
- data/src/core/ext/filters/client_channel/server_address.cc +4 -6
- data/src/core/ext/filters/client_channel/server_address.h +1 -3
- data/src/core/ext/filters/client_channel/service_config.cc +20 -22
- data/src/core/ext/filters/client_channel/service_config.h +26 -28
- data/src/core/ext/filters/client_channel/subchannel.cc +261 -160
- data/src/core/ext/filters/client_channel/subchannel.h +97 -23
- data/src/core/ext/filters/client_channel/subchannel_interface.h +113 -0
- data/src/core/ext/filters/message_size/message_size_filter.cc +12 -12
- data/src/core/ext/filters/message_size/message_size_filter.h +2 -2
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +50 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +31 -36
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +3 -2
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +71 -52
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +18 -3
- data/src/core/ext/transport/chttp2/transport/hpack_table.cc +5 -12
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +10 -1
- data/src/core/ext/transport/chttp2/transport/internal.h +3 -3
- data/src/core/ext/transport/chttp2/transport/parsing.cc +39 -57
- data/src/core/lib/channel/channelz.cc +136 -19
- data/src/core/lib/channel/channelz.h +36 -40
- data/src/core/lib/channel/channelz_registry.cc +74 -106
- data/src/core/lib/channel/channelz_registry.h +10 -28
- data/src/core/lib/channel/context.h +1 -1
- data/src/core/lib/channel/handshaker.cc +6 -0
- data/src/core/lib/compression/compression.cc +13 -8
- data/src/core/lib/compression/compression_internal.cc +14 -10
- data/src/core/lib/compression/compression_internal.h +1 -1
- data/src/core/lib/compression/stream_compression.cc +3 -2
- data/src/core/lib/compression/stream_compression.h +2 -2
- data/src/core/lib/compression/stream_compression_gzip.cc +9 -9
- data/src/core/lib/gpr/env.h +1 -1
- data/src/core/lib/gpr/string.cc +8 -1
- data/src/core/lib/gpr/string.h +6 -1
- data/src/core/lib/gprpp/fork.cc +1 -1
- data/src/core/lib/gprpp/fork.h +5 -1
- data/src/core/lib/gprpp/global_config.h +9 -0
- data/src/core/lib/gprpp/global_config_custom.h +1 -1
- data/src/core/lib/gprpp/inlined_vector.h +8 -0
- data/src/core/lib/gprpp/map.h +38 -21
- data/src/core/lib/gprpp/memory.h +2 -2
- data/src/core/lib/gprpp/orphanable.h +1 -1
- data/src/core/lib/gprpp/ref_counted.h +9 -4
- data/src/core/lib/http/httpcli.cc +3 -3
- data/src/core/lib/iomgr/buffer_list.h +1 -1
- data/src/core/lib/iomgr/call_combiner.cc +1 -1
- data/src/core/lib/iomgr/call_combiner.h +1 -1
- data/src/core/lib/iomgr/cfstream_handle.cc +3 -2
- data/src/core/lib/iomgr/cfstream_handle.h +4 -0
- data/src/core/lib/iomgr/error.cc +3 -3
- data/src/core/lib/iomgr/error.h +9 -3
- data/src/core/lib/iomgr/error_internal.h +1 -1
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +1 -1
- data/src/core/lib/iomgr/ev_posix.cc +3 -3
- data/src/core/lib/iomgr/ev_posix.h +3 -2
- data/src/core/lib/iomgr/ev_windows.cc +2 -2
- data/src/core/lib/iomgr/iomgr.cc +4 -4
- data/src/core/lib/iomgr/lockfree_event.cc +1 -1
- data/src/core/lib/iomgr/port.h +5 -1
- data/src/core/lib/iomgr/tcp_posix.cc +1 -3
- data/src/core/lib/iomgr/tcp_server.cc +5 -0
- data/src/core/lib/iomgr/tcp_server.h +24 -0
- data/src/core/lib/iomgr/tcp_server_custom.cc +11 -9
- data/src/core/lib/iomgr/tcp_server_posix.cc +72 -11
- data/src/core/lib/iomgr/tcp_server_utils_posix.h +3 -0
- data/src/core/lib/iomgr/tcp_server_windows.cc +11 -9
- data/src/core/lib/iomgr/tcp_uv.cc +5 -6
- data/src/core/lib/iomgr/timer.h +2 -1
- data/src/core/lib/iomgr/udp_server.cc +2 -2
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +1 -1
- data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +20 -2
- data/src/core/lib/security/credentials/ssl/ssl_credentials.h +2 -2
- data/src/core/lib/security/security_connector/security_connector.h +1 -1
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +1 -1
- data/src/core/lib/security/transport/auth_filters.h +3 -0
- data/src/core/lib/security/transport/client_auth_filter.cc +13 -0
- data/src/core/lib/security/transport/security_handshaker.cc +7 -7
- data/src/core/lib/slice/b64.h +2 -2
- data/src/core/lib/slice/slice.cc +82 -10
- data/src/core/lib/slice/slice_buffer.cc +49 -21
- data/src/core/lib/slice/slice_hash_table.h +2 -2
- data/src/core/lib/slice/slice_intern.cc +15 -16
- data/src/core/lib/slice/slice_internal.h +52 -0
- data/src/core/lib/slice/slice_string_helpers.cc +10 -1
- data/src/core/lib/slice/slice_string_helpers.h +3 -1
- data/src/core/lib/slice/slice_utils.h +50 -0
- data/src/core/lib/slice/slice_weak_hash_table.h +2 -2
- data/src/core/lib/surface/call.cc +14 -8
- data/src/core/lib/surface/channel.cc +89 -97
- data/src/core/lib/surface/channel.h +60 -6
- data/src/core/lib/surface/completion_queue.cc +49 -36
- data/src/core/lib/surface/completion_queue.h +2 -1
- data/src/core/lib/surface/server.cc +8 -8
- data/src/core/lib/surface/validate_metadata.cc +14 -8
- data/src/core/lib/surface/validate_metadata.h +13 -2
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/lib/transport/metadata.cc +56 -26
- data/src/core/lib/transport/metadata.h +91 -75
- data/src/core/lib/transport/static_metadata.cc +262 -176
- data/src/core/lib/transport/static_metadata.h +272 -180
- data/src/core/lib/transport/transport.cc +1 -1
- data/src/core/lib/transport/transport.h +8 -2
- data/src/core/tsi/alts/handshaker/alts_shared_resource.h +1 -1
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +5 -2
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +37 -35
@@ -77,7 +77,8 @@ bool grpc_cq_begin_op(grpc_completion_queue* cc, void* tag);
|
|
77
77
|
grpc_cq_begin_op */
|
78
78
|
void grpc_cq_end_op(grpc_completion_queue* cc, void* tag, grpc_error* error,
|
79
79
|
void (*done)(void* done_arg, grpc_cq_completion* storage),
|
80
|
-
void* done_arg, grpc_cq_completion* storage
|
80
|
+
void* done_arg, grpc_cq_completion* storage,
|
81
|
+
bool internal = false);
|
81
82
|
|
82
83
|
grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cc);
|
83
84
|
|
@@ -513,7 +513,7 @@ static void publish_call(grpc_server* server, call_data* calld, size_t cq_idx,
|
|
513
513
|
}
|
514
514
|
|
515
515
|
grpc_cq_end_op(calld->cq_new, rc->tag, GRPC_ERROR_NONE, done_request_event,
|
516
|
-
rc, &rc->completion);
|
516
|
+
rc, &rc->completion, true);
|
517
517
|
}
|
518
518
|
|
519
519
|
static void publish_new_rpc(void* arg, grpc_error* error) {
|
@@ -625,8 +625,8 @@ static void start_new_rpc(grpc_call_element* elem) {
|
|
625
625
|
if (chand->registered_methods && calld->path_set && calld->host_set) {
|
626
626
|
/* TODO(ctiller): unify these two searches */
|
627
627
|
/* check for an exact match with host */
|
628
|
-
hash = GRPC_MDSTR_KV_HASH(
|
629
|
-
|
628
|
+
hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash_internal(calld->host),
|
629
|
+
grpc_slice_hash_internal(calld->path));
|
630
630
|
for (i = 0; i <= chand->registered_method_max_probes; i++) {
|
631
631
|
rm = &chand->registered_methods[(hash + i) %
|
632
632
|
chand->registered_method_slots];
|
@@ -644,7 +644,7 @@ static void start_new_rpc(grpc_call_element* elem) {
|
|
644
644
|
return;
|
645
645
|
}
|
646
646
|
/* check for a wildcard method definition (no host set) */
|
647
|
-
hash = GRPC_MDSTR_KV_HASH(0,
|
647
|
+
hash = GRPC_MDSTR_KV_HASH(0, grpc_slice_hash_internal(calld->path));
|
648
648
|
for (i = 0; i <= chand->registered_method_max_probes; i++) {
|
649
649
|
rm = &chand->registered_methods[(hash + i) %
|
650
650
|
chand->registered_method_slots];
|
@@ -1194,14 +1194,14 @@ void grpc_server_setup_transport(
|
|
1194
1194
|
bool has_host;
|
1195
1195
|
grpc_slice method;
|
1196
1196
|
if (rm->host != nullptr) {
|
1197
|
-
host =
|
1197
|
+
host = grpc_slice_from_static_string(rm->host);
|
1198
1198
|
has_host = true;
|
1199
1199
|
} else {
|
1200
1200
|
has_host = false;
|
1201
1201
|
}
|
1202
|
-
method =
|
1203
|
-
hash = GRPC_MDSTR_KV_HASH(has_host ?
|
1204
|
-
|
1202
|
+
method = grpc_slice_from_static_string(rm->method);
|
1203
|
+
hash = GRPC_MDSTR_KV_HASH(has_host ? grpc_slice_hash_internal(host) : 0,
|
1204
|
+
grpc_slice_hash_internal(method));
|
1205
1205
|
for (probes = 0; chand->registered_methods[(hash + probes) % slots]
|
1206
1206
|
.server_registered_method != nullptr;
|
1207
1207
|
probes++)
|
@@ -24,12 +24,14 @@
|
|
24
24
|
#include <grpc/grpc.h>
|
25
25
|
#include <grpc/support/alloc.h>
|
26
26
|
|
27
|
+
#include "src/core/lib/gprpp/memory.h"
|
27
28
|
#include "src/core/lib/iomgr/error.h"
|
28
29
|
#include "src/core/lib/slice/slice_internal.h"
|
29
30
|
#include "src/core/lib/slice/slice_string_helpers.h"
|
30
31
|
#include "src/core/lib/surface/validate_metadata.h"
|
31
32
|
|
32
|
-
static grpc_error* conforms_to(grpc_slice slice,
|
33
|
+
static grpc_error* conforms_to(const grpc_slice& slice,
|
34
|
+
const uint8_t* legal_bits,
|
33
35
|
const char* err_desc) {
|
34
36
|
const uint8_t* p = GRPC_SLICE_START_PTR(slice);
|
35
37
|
const uint8_t* e = GRPC_SLICE_END_PTR(slice);
|
@@ -38,13 +40,12 @@ static grpc_error* conforms_to(grpc_slice slice, const uint8_t* legal_bits,
|
|
38
40
|
int byte = idx / 8;
|
39
41
|
int bit = idx % 8;
|
40
42
|
if ((legal_bits[byte] & (1 << bit)) == 0) {
|
41
|
-
char* dump = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
|
42
43
|
grpc_error* error = grpc_error_set_str(
|
43
44
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_desc),
|
44
45
|
GRPC_ERROR_INT_OFFSET,
|
45
46
|
p - GRPC_SLICE_START_PTR(slice)),
|
46
|
-
GRPC_ERROR_STR_RAW_BYTES,
|
47
|
-
|
47
|
+
GRPC_ERROR_STR_RAW_BYTES,
|
48
|
+
grpc_dump_slice_to_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII));
|
48
49
|
return error;
|
49
50
|
}
|
50
51
|
}
|
@@ -57,7 +58,7 @@ static int error2int(grpc_error* error) {
|
|
57
58
|
return r;
|
58
59
|
}
|
59
60
|
|
60
|
-
grpc_error* grpc_validate_header_key_is_legal(grpc_slice slice) {
|
61
|
+
grpc_error* grpc_validate_header_key_is_legal(const grpc_slice& slice) {
|
61
62
|
static const uint8_t legal_header_bits[256 / 8] = {
|
62
63
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00,
|
63
64
|
0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
@@ -77,7 +78,8 @@ int grpc_header_key_is_legal(grpc_slice slice) {
|
|
77
78
|
return error2int(grpc_validate_header_key_is_legal(slice));
|
78
79
|
}
|
79
80
|
|
80
|
-
grpc_error* grpc_validate_header_nonbin_value_is_legal(
|
81
|
+
grpc_error* grpc_validate_header_nonbin_value_is_legal(
|
82
|
+
const grpc_slice& slice) {
|
81
83
|
static const uint8_t legal_header_bits[256 / 8] = {
|
82
84
|
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
83
85
|
0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
@@ -89,7 +91,11 @@ int grpc_header_nonbin_value_is_legal(grpc_slice slice) {
|
|
89
91
|
return error2int(grpc_validate_header_nonbin_value_is_legal(slice));
|
90
92
|
}
|
91
93
|
|
94
|
+
int grpc_is_binary_header_internal(const grpc_slice& slice) {
|
95
|
+
return grpc_key_is_binary_header(GRPC_SLICE_START_PTR(slice),
|
96
|
+
GRPC_SLICE_LENGTH(slice));
|
97
|
+
}
|
98
|
+
|
92
99
|
int grpc_is_binary_header(grpc_slice slice) {
|
93
|
-
|
94
|
-
return 0 == memcmp(GRPC_SLICE_END_PTR(slice) - 4, "-bin", 4);
|
100
|
+
return grpc_is_binary_header_internal(slice);
|
95
101
|
}
|
@@ -24,7 +24,18 @@
|
|
24
24
|
#include <grpc/slice.h>
|
25
25
|
#include "src/core/lib/iomgr/error.h"
|
26
26
|
|
27
|
-
grpc_error* grpc_validate_header_key_is_legal(grpc_slice slice);
|
28
|
-
grpc_error* grpc_validate_header_nonbin_value_is_legal(grpc_slice slice);
|
27
|
+
grpc_error* grpc_validate_header_key_is_legal(const grpc_slice& slice);
|
28
|
+
grpc_error* grpc_validate_header_nonbin_value_is_legal(const grpc_slice& slice);
|
29
|
+
|
30
|
+
int grpc_is_binary_header_internal(const grpc_slice& slice);
|
31
|
+
inline int grpc_key_is_binary_header(const uint8_t* buf, size_t length) {
|
32
|
+
if (length < 5) return 0;
|
33
|
+
return 0 == memcmp(buf + length - 4, "-bin", 4);
|
34
|
+
}
|
35
|
+
inline int grpc_is_refcounted_slice_binary_header(const grpc_slice& slice) {
|
36
|
+
GPR_DEBUG_ASSERT(slice.refcount != nullptr);
|
37
|
+
return grpc_key_is_binary_header(slice.data.refcounted.bytes,
|
38
|
+
slice.data.refcounted.length);
|
39
|
+
}
|
29
40
|
|
30
41
|
#endif /* GRPC_CORE_LIB_SURFACE_VALIDATE_METADATA_H */
|
@@ -43,6 +43,7 @@
|
|
43
43
|
|
44
44
|
using grpc_core::AllocatedMetadata;
|
45
45
|
using grpc_core::InternedMetadata;
|
46
|
+
using grpc_core::StaticMetadata;
|
46
47
|
using grpc_core::UserData;
|
47
48
|
|
48
49
|
/* There are two kinds of mdelem and mdstr instances.
|
@@ -100,15 +101,20 @@ void grpc_mdelem_trace_unref(void* md, const grpc_slice& key,
|
|
100
101
|
#define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity))
|
101
102
|
#define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1))
|
102
103
|
|
104
|
+
void StaticMetadata::HashInit() {
|
105
|
+
uint32_t k_hash = grpc_slice_hash_internal(kv_.key);
|
106
|
+
uint32_t v_hash = grpc_slice_hash_internal(kv_.value);
|
107
|
+
hash_ = GRPC_MDSTR_KV_HASH(k_hash, v_hash);
|
108
|
+
}
|
109
|
+
|
103
110
|
AllocatedMetadata::AllocatedMetadata(const grpc_slice& key,
|
104
111
|
const grpc_slice& value)
|
105
|
-
:
|
106
|
-
|
107
|
-
refcnt_(1) {
|
112
|
+
: RefcountedMdBase(grpc_slice_ref_internal(key),
|
113
|
+
grpc_slice_ref_internal(value)) {
|
108
114
|
#ifndef NDEBUG
|
109
115
|
if (grpc_trace_metadata.enabled()) {
|
110
|
-
char* key_str = grpc_slice_to_c_string(
|
111
|
-
char* value_str = grpc_slice_to_c_string(
|
116
|
+
char* key_str = grpc_slice_to_c_string(key);
|
117
|
+
char* value_str = grpc_slice_to_c_string(value);
|
112
118
|
gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%" PRIdPTR ": '%s' = '%s'", this,
|
113
119
|
RefValue(), key_str, value_str);
|
114
120
|
gpr_free(key_str);
|
@@ -118,8 +124,8 @@ AllocatedMetadata::AllocatedMetadata(const grpc_slice& key,
|
|
118
124
|
}
|
119
125
|
|
120
126
|
AllocatedMetadata::~AllocatedMetadata() {
|
121
|
-
grpc_slice_unref_internal(
|
122
|
-
grpc_slice_unref_internal(
|
127
|
+
grpc_slice_unref_internal(key());
|
128
|
+
grpc_slice_unref_internal(value());
|
123
129
|
void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED);
|
124
130
|
if (user_data) {
|
125
131
|
destroy_user_data_func destroy_user_data =
|
@@ -131,15 +137,13 @@ AllocatedMetadata::~AllocatedMetadata() {
|
|
131
137
|
InternedMetadata::InternedMetadata(const grpc_slice& key,
|
132
138
|
const grpc_slice& value, uint32_t hash,
|
133
139
|
InternedMetadata* next)
|
134
|
-
:
|
135
|
-
|
136
|
-
refcnt_(1),
|
137
|
-
hash_(hash),
|
140
|
+
: RefcountedMdBase(grpc_slice_ref_internal(key),
|
141
|
+
grpc_slice_ref_internal(value), hash),
|
138
142
|
link_(next) {
|
139
143
|
#ifndef NDEBUG
|
140
144
|
if (grpc_trace_metadata.enabled()) {
|
141
|
-
char* key_str = grpc_slice_to_c_string(
|
142
|
-
char* value_str = grpc_slice_to_c_string(
|
145
|
+
char* key_str = grpc_slice_to_c_string(key);
|
146
|
+
char* value_str = grpc_slice_to_c_string(value);
|
143
147
|
gpr_log(GPR_DEBUG, "ELM NEW:%p:%" PRIdPTR ": '%s' = '%s'", this,
|
144
148
|
RefValue(), key_str, value_str);
|
145
149
|
gpr_free(key_str);
|
@@ -149,8 +153,8 @@ InternedMetadata::InternedMetadata(const grpc_slice& key,
|
|
149
153
|
}
|
150
154
|
|
151
155
|
InternedMetadata::~InternedMetadata() {
|
152
|
-
grpc_slice_unref_internal(
|
153
|
-
grpc_slice_unref_internal(
|
156
|
+
grpc_slice_unref_internal(key());
|
157
|
+
grpc_slice_unref_internal(value());
|
154
158
|
void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED);
|
155
159
|
if (user_data) {
|
156
160
|
destroy_user_data_func destroy_user_data =
|
@@ -223,17 +227,20 @@ void grpc_mdctx_global_shutdown() {
|
|
223
227
|
}
|
224
228
|
}
|
225
229
|
|
230
|
+
#ifndef NDEBUG
|
226
231
|
static int is_mdelem_static(grpc_mdelem e) {
|
227
|
-
return GRPC_MDELEM_DATA(e) >=
|
228
|
-
|
232
|
+
return reinterpret_cast<grpc_core::StaticMetadata*>(GRPC_MDELEM_DATA(e)) >=
|
233
|
+
&grpc_static_mdelem_table[0] &&
|
234
|
+
reinterpret_cast<grpc_core::StaticMetadata*>(GRPC_MDELEM_DATA(e)) <
|
229
235
|
&grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
|
230
236
|
}
|
237
|
+
#endif
|
231
238
|
|
232
239
|
void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) {
|
233
240
|
#ifndef NDEBUG
|
234
241
|
if (grpc_trace_metadata.enabled()) {
|
235
|
-
char* key_str = grpc_slice_to_c_string(
|
236
|
-
char* value_str = grpc_slice_to_c_string(
|
242
|
+
char* key_str = grpc_slice_to_c_string(key());
|
243
|
+
char* value_str = grpc_slice_to_c_string(value());
|
237
244
|
intptr_t value = RefValue();
|
238
245
|
gpr_log(__FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG,
|
239
246
|
"ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", this, value,
|
@@ -323,8 +330,8 @@ grpc_mdelem grpc_mdelem_create(
|
|
323
330
|
}
|
324
331
|
}
|
325
332
|
|
326
|
-
uint32_t hash =
|
327
|
-
|
333
|
+
uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash_refcounted(key),
|
334
|
+
grpc_slice_hash_refcounted(value));
|
328
335
|
InternedMetadata* md;
|
329
336
|
mdtab_shard* shard = &g_shards[SHARD_IDX(hash)];
|
330
337
|
size_t idx;
|
@@ -391,8 +398,11 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) {
|
|
391
398
|
case GRPC_MDELEM_STORAGE_EXTERNAL:
|
392
399
|
return nullptr;
|
393
400
|
case GRPC_MDELEM_STORAGE_STATIC:
|
394
|
-
return
|
395
|
-
|
401
|
+
return reinterpret_cast<void*>(
|
402
|
+
grpc_static_mdelem_user_data
|
403
|
+
[reinterpret_cast<grpc_core::StaticMetadata*>(
|
404
|
+
GRPC_MDELEM_DATA(md)) -
|
405
|
+
grpc_static_mdelem_table]);
|
396
406
|
case GRPC_MDELEM_STORAGE_ALLOCATED: {
|
397
407
|
auto* am = reinterpret_cast<AllocatedMetadata*>(GRPC_MDELEM_DATA(md));
|
398
408
|
return get_user_data(am->user_data(), destroy_func);
|
@@ -430,15 +440,18 @@ void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*),
|
|
430
440
|
return nullptr;
|
431
441
|
case GRPC_MDELEM_STORAGE_STATIC:
|
432
442
|
destroy_func(data);
|
433
|
-
return
|
434
|
-
|
443
|
+
return reinterpret_cast<void*>(
|
444
|
+
grpc_static_mdelem_user_data
|
445
|
+
[reinterpret_cast<grpc_core::StaticMetadata*>(
|
446
|
+
GRPC_MDELEM_DATA(md)) -
|
447
|
+
grpc_static_mdelem_table]);
|
435
448
|
case GRPC_MDELEM_STORAGE_ALLOCATED: {
|
436
449
|
auto* am = reinterpret_cast<AllocatedMetadata*>(GRPC_MDELEM_DATA(md));
|
437
450
|
return set_user_data(am->user_data(), destroy_func, data);
|
438
451
|
}
|
439
452
|
case GRPC_MDELEM_STORAGE_INTERNED: {
|
440
453
|
auto* im = reinterpret_cast<InternedMetadata*> GRPC_MDELEM_DATA(md);
|
441
|
-
|
454
|
+
GPR_DEBUG_ASSERT(!is_mdelem_static(md));
|
442
455
|
return set_user_data(im->user_data(), destroy_func, data);
|
443
456
|
}
|
444
457
|
}
|
@@ -482,3 +495,20 @@ void grpc_mdelem_do_unref(grpc_mdelem gmd DEBUG_ARGS) {
|
|
482
495
|
}
|
483
496
|
}
|
484
497
|
}
|
498
|
+
|
499
|
+
void grpc_mdelem_on_final_unref(grpc_mdelem_data_storage storage, void* ptr,
|
500
|
+
uint32_t hash DEBUG_ARGS) {
|
501
|
+
switch (storage) {
|
502
|
+
case GRPC_MDELEM_STORAGE_EXTERNAL:
|
503
|
+
case GRPC_MDELEM_STORAGE_STATIC:
|
504
|
+
return;
|
505
|
+
case GRPC_MDELEM_STORAGE_INTERNED: {
|
506
|
+
note_disposed_interned_metadata(hash);
|
507
|
+
break;
|
508
|
+
}
|
509
|
+
case GRPC_MDELEM_STORAGE_ALLOCATED: {
|
510
|
+
grpc_core::Delete(reinterpret_cast<AllocatedMetadata*>(ptr));
|
511
|
+
break;
|
512
|
+
}
|
513
|
+
}
|
514
|
+
}
|
@@ -21,7 +21,7 @@
|
|
21
21
|
|
22
22
|
#include <grpc/support/port_platform.h>
|
23
23
|
|
24
|
-
#include
|
24
|
+
#include <grpc/impl/codegen/log.h>
|
25
25
|
|
26
26
|
#include <grpc/grpc.h>
|
27
27
|
#include <grpc/slice.h>
|
@@ -30,6 +30,7 @@
|
|
30
30
|
#include "src/core/lib/gpr/useful.h"
|
31
31
|
#include "src/core/lib/gprpp/atomic.h"
|
32
32
|
#include "src/core/lib/gprpp/sync.h"
|
33
|
+
#include "src/core/lib/slice/slice_utils.h"
|
33
34
|
|
34
35
|
extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata;
|
35
36
|
|
@@ -79,17 +80,22 @@ typedef struct grpc_mdelem_data {
|
|
79
80
|
this bit set in their integer value */
|
80
81
|
#define GRPC_MDELEM_STORAGE_INTERNED_BIT 1
|
81
82
|
|
83
|
+
/* External and static storage metadata has no refcount to ref/unref. Allocated
|
84
|
+
* and interned metadata do have a refcount. Metadata ref and unref methods use
|
85
|
+
* a switch statement on this enum to determine which behaviour to execute.
|
86
|
+
* Keeping the no-ref cases together and the ref-cases together leads to
|
87
|
+
* slightly better code generation (9 inlined instructions rather than 10). */
|
82
88
|
typedef enum {
|
83
89
|
/* memory pointed to by grpc_mdelem::payload is owned by an external system */
|
84
90
|
GRPC_MDELEM_STORAGE_EXTERNAL = 0,
|
85
|
-
/* memory
|
86
|
-
|
87
|
-
GRPC_MDELEM_STORAGE_INTERNED = GRPC_MDELEM_STORAGE_INTERNED_BIT,
|
91
|
+
/* memory is in the static metadata table */
|
92
|
+
GRPC_MDELEM_STORAGE_STATIC = GRPC_MDELEM_STORAGE_INTERNED_BIT,
|
88
93
|
/* memory pointed to by grpc_mdelem::payload is allocated by the metadata
|
89
94
|
system */
|
90
95
|
GRPC_MDELEM_STORAGE_ALLOCATED = 2,
|
91
|
-
/* memory is
|
92
|
-
|
96
|
+
/* memory pointed to by grpc_mdelem::payload is interned by the metadata
|
97
|
+
system */
|
98
|
+
GRPC_MDELEM_STORAGE_INTERNED = 2 | GRPC_MDELEM_STORAGE_INTERNED_BIT,
|
93
99
|
} grpc_mdelem_data_storage;
|
94
100
|
|
95
101
|
struct grpc_mdelem {
|
@@ -138,7 +144,17 @@ bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);
|
|
138
144
|
* grpc_mdelem_eq and remove unnecessary checks. */
|
139
145
|
inline bool grpc_mdelem_static_value_eq(grpc_mdelem a, grpc_mdelem b_static) {
|
140
146
|
if (a.payload == b_static.payload) return true;
|
141
|
-
return
|
147
|
+
return grpc_slice_eq_static_interned(GRPC_MDVALUE(a), GRPC_MDVALUE(b_static));
|
148
|
+
}
|
149
|
+
#define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL)
|
150
|
+
|
151
|
+
inline bool grpc_mdelem_both_interned_eq(grpc_mdelem a_interned,
|
152
|
+
grpc_mdelem b_interned) {
|
153
|
+
GPR_DEBUG_ASSERT(GRPC_MDELEM_IS_INTERNED(a_interned) ||
|
154
|
+
GRPC_MDISNULL(a_interned));
|
155
|
+
GPR_DEBUG_ASSERT(GRPC_MDELEM_IS_INTERNED(b_interned) ||
|
156
|
+
GRPC_MDISNULL(b_interned));
|
157
|
+
return a_interned.payload == b_interned.payload;
|
142
158
|
}
|
143
159
|
|
144
160
|
/* Mutator and accessor for grpc_mdelem user data. The destructor function
|
@@ -168,17 +184,34 @@ struct UserData {
|
|
168
184
|
grpc_core::Atomic<void*> data;
|
169
185
|
};
|
170
186
|
|
171
|
-
class
|
187
|
+
class StaticMetadata {
|
172
188
|
public:
|
173
|
-
|
174
|
-
|
189
|
+
StaticMetadata(const grpc_slice& key, const grpc_slice& value)
|
190
|
+
: kv_({key, value}), hash_(0) {}
|
175
191
|
|
176
|
-
|
177
|
-
};
|
192
|
+
const grpc_mdelem_data& data() const { return kv_; }
|
178
193
|
|
179
|
-
|
180
|
-
|
181
|
-
|
194
|
+
void HashInit();
|
195
|
+
uint32_t hash() { return hash_; }
|
196
|
+
|
197
|
+
private:
|
198
|
+
grpc_mdelem_data kv_;
|
199
|
+
|
200
|
+
/* private only data */
|
201
|
+
uint32_t hash_;
|
202
|
+
};
|
203
|
+
|
204
|
+
class RefcountedMdBase {
|
205
|
+
public:
|
206
|
+
RefcountedMdBase(const grpc_slice& key, const grpc_slice& value)
|
207
|
+
: key_(key), value_(value), refcnt_(1) {}
|
208
|
+
RefcountedMdBase(const grpc_slice& key, const grpc_slice& value,
|
209
|
+
uint32_t hash)
|
210
|
+
: key_(key), value_(value), refcnt_(1), hash_(hash) {}
|
211
|
+
|
212
|
+
const grpc_slice& key() const { return key_; }
|
213
|
+
const grpc_slice& value() const { return value_; }
|
214
|
+
uint32_t hash() { return hash_; }
|
182
215
|
|
183
216
|
#ifndef NDEBUG
|
184
217
|
void Ref(const char* file, int line) {
|
@@ -190,92 +223,65 @@ class InternedMetadata {
|
|
190
223
|
grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line);
|
191
224
|
return Unref();
|
192
225
|
}
|
193
|
-
#
|
194
|
-
// We define a naked Ref() in the else-clause to make sure we don't
|
195
|
-
// inadvertently skip the assert on debug builds.
|
226
|
+
#endif
|
196
227
|
void Ref() {
|
197
228
|
/* we can assume the ref count is >= 1 as the application is calling
|
198
229
|
this function - meaning that no adjustment to mdtab_free is necessary,
|
199
230
|
simplifying the logic here to be just an atomic increment */
|
200
231
|
refcnt_.FetchAdd(1, MemoryOrder::RELAXED);
|
201
232
|
}
|
202
|
-
#endif // ifndef NDEBUG
|
203
233
|
bool Unref() {
|
204
234
|
const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL);
|
205
235
|
GPR_DEBUG_ASSERT(prior > 0);
|
206
236
|
return prior == 1;
|
207
237
|
}
|
208
238
|
|
209
|
-
|
210
|
-
|
211
|
-
const grpc_slice& value() const { return value_; }
|
212
|
-
UserData* user_data() { return &user_data_; }
|
213
|
-
uint32_t hash() { return hash_; }
|
214
|
-
InternedMetadata* bucket_next() { return link_.next; }
|
215
|
-
void set_bucket_next(InternedMetadata* md) { link_.next = md; }
|
216
|
-
|
217
|
-
static size_t CleanupLinkedMetadata(BucketLink* head);
|
218
|
-
|
219
|
-
private:
|
239
|
+
protected:
|
240
|
+
intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); }
|
220
241
|
bool AllRefsDropped() { return refcnt_.Load(MemoryOrder::ACQUIRE) == 0; }
|
221
242
|
bool FirstRef() { return refcnt_.FetchAdd(1, MemoryOrder::RELAXED) == 0; }
|
222
|
-
intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); }
|
223
243
|
|
244
|
+
private:
|
224
245
|
/* must be byte compatible with grpc_mdelem_data */
|
225
246
|
grpc_slice key_;
|
226
247
|
grpc_slice value_;
|
227
|
-
|
228
|
-
/* private only data */
|
229
248
|
grpc_core::Atomic<intptr_t> refcnt_;
|
230
|
-
uint32_t hash_;
|
249
|
+
uint32_t hash_ = 0;
|
250
|
+
};
|
231
251
|
|
232
|
-
|
252
|
+
class InternedMetadata : public RefcountedMdBase {
|
253
|
+
public:
|
254
|
+
struct BucketLink {
|
255
|
+
explicit BucketLink(InternedMetadata* md) : next(md) {}
|
256
|
+
|
257
|
+
InternedMetadata* next = nullptr;
|
258
|
+
};
|
259
|
+
|
260
|
+
InternedMetadata(const grpc_slice& key, const grpc_slice& value,
|
261
|
+
uint32_t hash, InternedMetadata* next);
|
262
|
+
~InternedMetadata();
|
263
|
+
|
264
|
+
void RefWithShardLocked(mdtab_shard* shard);
|
265
|
+
UserData* user_data() { return &user_data_; }
|
266
|
+
InternedMetadata* bucket_next() { return link_.next; }
|
267
|
+
void set_bucket_next(InternedMetadata* md) { link_.next = md; }
|
233
268
|
|
269
|
+
static size_t CleanupLinkedMetadata(BucketLink* head);
|
270
|
+
|
271
|
+
private:
|
272
|
+
UserData user_data_;
|
234
273
|
BucketLink link_;
|
235
274
|
};
|
236
275
|
|
237
276
|
/* Shadow structure for grpc_mdelem_data for allocated elements */
|
238
|
-
class AllocatedMetadata {
|
277
|
+
class AllocatedMetadata : public RefcountedMdBase {
|
239
278
|
public:
|
240
279
|
AllocatedMetadata(const grpc_slice& key, const grpc_slice& value);
|
241
280
|
~AllocatedMetadata();
|
242
281
|
|
243
|
-
const grpc_slice& key() const { return key_; }
|
244
|
-
const grpc_slice& value() const { return value_; }
|
245
282
|
UserData* user_data() { return &user_data_; }
|
246
283
|
|
247
|
-
#ifndef NDEBUG
|
248
|
-
void Ref(const char* file, int line) {
|
249
|
-
grpc_mdelem_trace_ref(this, key_, value_, RefValue(), file, line);
|
250
|
-
Ref();
|
251
|
-
}
|
252
|
-
bool Unref(const char* file, int line) {
|
253
|
-
grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line);
|
254
|
-
return Unref();
|
255
|
-
}
|
256
|
-
#endif // ifndef NDEBUG
|
257
|
-
void Ref() {
|
258
|
-
/* we can assume the ref count is >= 1 as the application is calling
|
259
|
-
this function - meaning that no adjustment to mdtab_free is necessary,
|
260
|
-
simplifying the logic here to be just an atomic increment */
|
261
|
-
refcnt_.FetchAdd(1, MemoryOrder::RELAXED);
|
262
|
-
}
|
263
|
-
bool Unref() {
|
264
|
-
const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL);
|
265
|
-
GPR_DEBUG_ASSERT(prior > 0);
|
266
|
-
return prior == 1;
|
267
|
-
}
|
268
|
-
|
269
284
|
private:
|
270
|
-
intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); }
|
271
|
-
|
272
|
-
/* must be byte compatible with grpc_mdelem_data */
|
273
|
-
grpc_slice key_;
|
274
|
-
grpc_slice value_;
|
275
|
-
|
276
|
-
/* private only data */
|
277
|
-
grpc_core::Atomic<intptr_t> refcnt_;
|
278
|
-
|
279
285
|
UserData user_data_;
|
280
286
|
};
|
281
287
|
|
@@ -320,30 +326,40 @@ inline grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd) {
|
|
320
326
|
|
321
327
|
#ifndef NDEBUG
|
322
328
|
#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__)
|
323
|
-
void
|
329
|
+
void grpc_mdelem_on_final_unref(grpc_mdelem_data_storage storage, void* ptr,
|
330
|
+
uint32_t hash, const char* file, int line);
|
324
331
|
inline void grpc_mdelem_unref(grpc_mdelem gmd, const char* file, int line) {
|
325
332
|
#else
|
326
333
|
#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s))
|
327
|
-
void
|
334
|
+
void grpc_mdelem_on_final_unref(grpc_mdelem_data_storage storage, void* ptr,
|
335
|
+
uint32_t hash);
|
328
336
|
inline void grpc_mdelem_unref(grpc_mdelem gmd) {
|
329
337
|
#endif
|
330
|
-
|
338
|
+
const grpc_mdelem_data_storage storage = GRPC_MDELEM_STORAGE(gmd);
|
339
|
+
switch (storage) {
|
331
340
|
case GRPC_MDELEM_STORAGE_EXTERNAL:
|
332
341
|
case GRPC_MDELEM_STORAGE_STATIC:
|
333
342
|
return;
|
334
343
|
case GRPC_MDELEM_STORAGE_INTERNED:
|
335
344
|
case GRPC_MDELEM_STORAGE_ALLOCATED:
|
345
|
+
auto* md =
|
346
|
+
reinterpret_cast<grpc_core::RefcountedMdBase*> GRPC_MDELEM_DATA(gmd);
|
347
|
+
/* once the refcount hits zero, some other thread can come along and
|
348
|
+
free an interned md at any time: it's unsafe from this point on to
|
349
|
+
access it so we read the hash now. */
|
350
|
+
uint32_t hash = md->hash();
|
351
|
+
if (GPR_UNLIKELY(md->Unref())) {
|
336
352
|
#ifndef NDEBUG
|
337
|
-
|
353
|
+
grpc_mdelem_on_final_unref(storage, md, hash, file, line);
|
338
354
|
#else
|
339
|
-
|
355
|
+
grpc_mdelem_on_final_unref(storage, md, hash);
|
340
356
|
#endif
|
357
|
+
}
|
341
358
|
return;
|
342
359
|
}
|
343
360
|
}
|
344
361
|
|
345
362
|
#define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL)
|
346
|
-
#define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL)
|
347
363
|
|
348
364
|
/* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */
|
349
365
|
#define GRPC_MDELEM_LENGTH(e) \
|