grpc 1.22.0 → 1.23.0
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 +487 -649
- data/include/grpc/grpc_security.h +25 -0
- data/include/grpc/impl/codegen/grpc_types.h +11 -2
- data/include/grpc/impl/codegen/port_platform.h +12 -0
- data/src/core/ext/filters/client_channel/backup_poller.cc +4 -2
- data/src/core/ext/filters/client_channel/client_channel.cc +477 -182
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +25 -16
- data/src/core/ext/filters/client_channel/client_channel_channelz.h +11 -6
- data/src/core/ext/filters/client_channel/connector.h +10 -2
- data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -3
- data/src/core/ext/filters/client_channel/http_proxy.cc +9 -10
- data/src/core/ext/filters/client_channel/lb_policy.cc +2 -17
- data/src/core/ext/filters/client_channel/lb_policy.h +36 -8
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +22 -8
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +86 -52
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +7 -0
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +73 -72
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +8 -12
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +25 -101
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +5 -5
- data/src/core/ext/filters/client_channel/parse_address.cc +29 -26
- data/src/core/ext/filters/client_channel/resolver.h +3 -11
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +5 -3
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +405 -82
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +44 -51
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +0 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +0 -1
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +11 -6
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +130 -65
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +8 -3
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +31 -14
- data/src/core/ext/filters/client_channel/resolver_factory.h +4 -0
- data/src/core/ext/filters/client_channel/resolver_registry.cc +11 -0
- data/src/core/ext/filters/client_channel/resolver_registry.h +3 -0
- data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +10 -49
- data/src/core/ext/filters/client_channel/resolving_lb_policy.h +1 -14
- data/src/core/ext/filters/client_channel/retry_throttle.h +2 -3
- data/src/core/ext/filters/client_channel/subchannel.cc +65 -58
- data/src/core/ext/filters/client_channel/subchannel.h +65 -45
- data/src/core/ext/filters/client_channel/subchannel_interface.h +15 -30
- data/src/core/ext/filters/client_idle/client_idle_filter.cc +262 -0
- data/src/core/ext/filters/http/client/http_client_filter.cc +4 -5
- data/src/core/ext/filters/http/client_authority_filter.cc +2 -2
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +140 -152
- data/src/core/ext/filters/max_age/max_age_filter.cc +3 -3
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +3 -4
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +7 -6
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +63 -38
- data/src/core/ext/transport/chttp2/transport/context_list.cc +3 -1
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -4
- data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -0
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +8 -0
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +7 -0
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +1 -0
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +37 -22
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +136 -81
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -0
- data/src/core/ext/transport/chttp2/transport/hpack_table.cc +7 -166
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +41 -15
- data/src/core/ext/transport/chttp2/transport/internal.h +13 -2
- data/src/core/ext/transport/chttp2/transport/parsing.cc +35 -22
- data/src/core/ext/transport/chttp2/transport/stream_map.cc +28 -18
- data/src/core/ext/transport/chttp2/transport/writing.cc +1 -0
- data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
- data/src/core/lib/channel/channelz.cc +80 -33
- data/src/core/lib/channel/channelz.h +28 -13
- data/src/core/lib/compression/compression.cc +1 -2
- data/src/core/lib/compression/compression_args.cc +13 -6
- data/src/core/lib/compression/compression_args.h +3 -2
- data/src/core/lib/compression/compression_internal.cc +1 -1
- data/src/core/lib/gpr/env_linux.cc +10 -21
- data/src/core/lib/gpr/env_posix.cc +0 -5
- data/src/core/lib/gpr/string.cc +7 -2
- data/src/core/lib/gpr/string.h +1 -0
- data/src/core/lib/gpr/sync_posix.cc +0 -129
- data/src/core/lib/gprpp/debug_location.h +3 -2
- data/src/core/lib/gprpp/fork.cc +14 -21
- data/src/core/lib/gprpp/fork.h +15 -4
- data/src/core/lib/gprpp/host_port.cc +118 -0
- data/src/core/lib/{gpr → gprpp}/host_port.h +27 -11
- data/src/core/lib/gprpp/map.h +25 -0
- data/src/core/lib/gprpp/memory.h +26 -9
- data/src/core/lib/gprpp/ref_counted.h +63 -21
- data/src/core/lib/gprpp/string_view.h +143 -0
- data/src/core/lib/gprpp/thd.h +10 -1
- data/src/core/lib/gprpp/thd_posix.cc +25 -0
- data/src/core/lib/gprpp/thd_windows.cc +9 -1
- data/src/core/lib/http/httpcli_security_connector.cc +3 -1
- data/src/core/lib/iomgr/cfstream_handle.cc +6 -1
- data/src/core/lib/iomgr/cfstream_handle.h +8 -2
- data/src/core/lib/iomgr/combiner.cc +4 -4
- data/src/core/lib/iomgr/error.cc +18 -8
- data/src/core/lib/iomgr/error.h +2 -0
- data/src/core/lib/iomgr/ev_posix.cc +4 -2
- data/src/core/lib/iomgr/executor.cc +4 -1
- data/src/core/lib/iomgr/executor/mpmcqueue.cc +183 -0
- data/src/core/lib/iomgr/executor/mpmcqueue.h +178 -0
- data/src/core/lib/iomgr/executor/threadpool.cc +138 -0
- data/src/core/lib/iomgr/executor/threadpool.h +153 -0
- data/src/core/lib/iomgr/fork_posix.cc +4 -2
- data/src/core/lib/iomgr/iocp_windows.cc +2 -2
- data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +14 -0
- data/src/core/lib/iomgr/iomgr_uv.cc +3 -0
- data/src/core/lib/iomgr/lockfree_event.cc +3 -3
- data/src/core/lib/iomgr/resolve_address_custom.cc +16 -20
- data/src/core/lib/iomgr/resolve_address_posix.cc +8 -10
- data/src/core/lib/iomgr/resolve_address_windows.cc +6 -8
- data/src/core/lib/iomgr/sockaddr_utils.cc +5 -3
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +0 -1
- data/src/core/lib/iomgr/socket_windows.h +1 -1
- data/src/core/lib/iomgr/tcp_client_cfstream.cc +7 -6
- data/src/core/lib/iomgr/tcp_client_custom.cc +1 -0
- data/src/core/lib/iomgr/tcp_custom.cc +4 -0
- data/src/core/lib/iomgr/tcp_posix.cc +8 -2
- data/src/core/lib/iomgr/tcp_server_custom.cc +1 -0
- data/src/core/lib/iomgr/tcp_server_windows.cc +1 -1
- data/src/core/lib/iomgr/tcp_windows.cc +7 -7
- data/src/core/lib/iomgr/timer_custom.cc +1 -0
- data/src/core/lib/iomgr/timer_manager.cc +0 -29
- data/src/core/lib/security/credentials/credentials.cc +84 -0
- data/src/core/lib/security/credentials/credentials.h +58 -2
- data/src/core/lib/security/credentials/jwt/json_token.cc +6 -2
- data/src/core/lib/security/credentials/jwt/json_token.h +1 -1
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +245 -24
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +16 -0
- data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +3 -2
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +21 -25
- data/src/core/lib/security/security_connector/local/local_security_connector.cc +3 -2
- data/src/core/lib/security/security_connector/security_connector.cc +1 -1
- data/src/core/lib/security/security_connector/security_connector.h +1 -1
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +19 -19
- data/src/core/lib/security/security_connector/ssl_utils.cc +26 -31
- data/src/core/lib/security/security_connector/ssl_utils.h +11 -8
- data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +16 -20
- data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +4 -3
- data/src/core/lib/security/transport/client_auth_filter.cc +1 -2
- data/src/core/lib/security/util/json_util.cc +19 -5
- data/src/core/lib/security/util/json_util.h +3 -1
- data/src/core/lib/slice/slice.cc +69 -50
- data/src/core/lib/slice/slice_buffer.cc +6 -5
- data/src/core/lib/slice/slice_hash_table.h +3 -7
- data/src/core/lib/slice/slice_intern.cc +130 -39
- data/src/core/lib/slice/slice_internal.h +8 -0
- data/src/core/lib/slice/slice_utils.h +120 -0
- data/src/core/lib/slice/slice_weak_hash_table.h +2 -7
- data/src/core/lib/surface/call.cc +8 -3
- data/src/core/lib/surface/channel.cc +31 -8
- data/src/core/lib/surface/completion_queue.cc +17 -7
- data/src/core/lib/surface/init_secure.cc +4 -1
- data/src/core/lib/surface/lame_client.cc +2 -2
- data/src/core/lib/surface/server.cc +34 -35
- data/src/core/lib/surface/server.h +8 -17
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/lib/transport/byte_stream.cc +3 -5
- data/src/core/lib/transport/byte_stream.h +1 -2
- data/src/core/lib/transport/error_utils.cc +10 -1
- data/src/core/lib/transport/metadata.cc +202 -35
- data/src/core/lib/transport/metadata.h +81 -6
- data/src/core/lib/transport/static_metadata.cc +1257 -465
- data/src/core/lib/transport/static_metadata.h +190 -347
- data/src/core/lib/transport/timeout_encoding.cc +7 -0
- data/src/core/lib/transport/timeout_encoding.h +3 -2
- data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +0 -1
- data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -7
- data/src/core/tsi/ssl_transport_security.cc +35 -43
- data/src/core/tsi/ssl_transport_security.h +2 -1
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
- data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
- data/src/ruby/lib/grpc/grpc.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +39 -33
- data/src/core/lib/gpr/host_port.cc +0 -98
@@ -34,31 +34,22 @@ extern grpc_core::TraceFlag grpc_server_channel_trace;
|
|
34
34
|
|
35
35
|
/* Add a listener to the server: when the server starts, it will call start,
|
36
36
|
and when it shuts down, it will call destroy */
|
37
|
-
void grpc_server_add_listener(
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
intptr_t socket_uuid);
|
37
|
+
void grpc_server_add_listener(
|
38
|
+
grpc_server* server, void* listener_arg,
|
39
|
+
void (*start)(grpc_server* server, void* arg, grpc_pollset** pollsets,
|
40
|
+
size_t npollsets),
|
41
|
+
void (*destroy)(grpc_server* server, void* arg, grpc_closure* on_done),
|
42
|
+
grpc_core::RefCountedPtr<grpc_core::channelz::ListenSocketNode> node);
|
44
43
|
|
45
44
|
/* Setup a transport - creates a channel stack, binds the transport to the
|
46
45
|
server */
|
47
46
|
void grpc_server_setup_transport(
|
48
47
|
grpc_server* server, grpc_transport* transport,
|
49
48
|
grpc_pollset* accepting_pollset, const grpc_channel_args* args,
|
50
|
-
grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode
|
49
|
+
const grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode>&
|
50
|
+
socket_node,
|
51
51
|
grpc_resource_user* resource_user = nullptr);
|
52
52
|
|
53
|
-
/* fills in the uuids of all sockets used for connections on this server */
|
54
|
-
void grpc_server_populate_server_sockets(
|
55
|
-
grpc_server* server, grpc_core::channelz::ChildSocketsList* server_sockets,
|
56
|
-
intptr_t start_idx);
|
57
|
-
|
58
|
-
/* fills in the uuids of all listen sockets on this server */
|
59
|
-
void grpc_server_populate_listen_sockets(
|
60
|
-
grpc_server* server, grpc_core::channelz::ChildRefsList* listen_sockets);
|
61
|
-
|
62
53
|
grpc_core::channelz::ServerNode* grpc_server_get_channelz_node(
|
63
54
|
grpc_server* server);
|
64
55
|
|
@@ -55,17 +55,15 @@ void SliceBufferByteStream::Orphan() {
|
|
55
55
|
|
56
56
|
bool SliceBufferByteStream::Next(size_t max_size_hint,
|
57
57
|
grpc_closure* on_complete) {
|
58
|
-
|
58
|
+
GPR_DEBUG_ASSERT(backing_buffer_.count > 0);
|
59
59
|
return true;
|
60
60
|
}
|
61
61
|
|
62
62
|
grpc_error* SliceBufferByteStream::Pull(grpc_slice* slice) {
|
63
|
-
if (shutdown_error_ != GRPC_ERROR_NONE) {
|
63
|
+
if (GPR_UNLIKELY(shutdown_error_ != GRPC_ERROR_NONE)) {
|
64
64
|
return GRPC_ERROR_REF(shutdown_error_);
|
65
65
|
}
|
66
|
-
|
67
|
-
*slice = grpc_slice_ref_internal(backing_buffer_.slices[cursor_]);
|
68
|
-
++cursor_;
|
66
|
+
*slice = grpc_slice_buffer_take_first(&backing_buffer_);
|
69
67
|
return GRPC_ERROR_NONE;
|
70
68
|
}
|
71
69
|
|
@@ -99,9 +99,8 @@ class SliceBufferByteStream : public ByteStream {
|
|
99
99
|
void Shutdown(grpc_error* error) override;
|
100
100
|
|
101
101
|
private:
|
102
|
-
grpc_slice_buffer backing_buffer_;
|
103
|
-
size_t cursor_ = 0;
|
104
102
|
grpc_error* shutdown_error_ = GRPC_ERROR_NONE;
|
103
|
+
grpc_slice_buffer backing_buffer_;
|
105
104
|
};
|
106
105
|
|
107
106
|
//
|
@@ -22,6 +22,7 @@
|
|
22
22
|
|
23
23
|
#include <grpc/support/string_util.h>
|
24
24
|
#include "src/core/lib/iomgr/error_internal.h"
|
25
|
+
#include "src/core/lib/slice/slice_internal.h"
|
25
26
|
#include "src/core/lib/transport/status_conversion.h"
|
26
27
|
|
27
28
|
static grpc_error* recursively_find_error_with_field(grpc_error* error,
|
@@ -52,7 +53,15 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline,
|
|
52
53
|
if (GPR_LIKELY(error == GRPC_ERROR_NONE)) {
|
53
54
|
if (code != nullptr) *code = GRPC_STATUS_OK;
|
54
55
|
if (slice != nullptr) {
|
55
|
-
|
56
|
+
// Normally, we call grpc_error_get_str(
|
57
|
+
// error, GRPC_ERROR_STR_GRPC_MESSAGE, slice).
|
58
|
+
// We can fastpath since we know that:
|
59
|
+
// 1) Error is null
|
60
|
+
// 2) which == GRPC_ERROR_STR_GRPC_MESSAGE
|
61
|
+
// 3) The resulting slice is statically known.
|
62
|
+
// 4) Said resulting slice is of length 0 ("").
|
63
|
+
// This means 3 movs, instead of 10s of instructions and a strlen.
|
64
|
+
*slice = grpc_core::ExternallyManagedSlice("");
|
56
65
|
}
|
57
66
|
if (http_error != nullptr) {
|
58
67
|
*http_error = GRPC_HTTP2_NO_ERROR;
|
@@ -68,8 +68,8 @@ void grpc_mdelem_trace_ref(void* md, const grpc_slice& key,
|
|
68
68
|
char* key_str = grpc_slice_to_c_string(key);
|
69
69
|
char* value_str = grpc_slice_to_c_string(value);
|
70
70
|
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
71
|
-
"
|
72
|
-
refcnt + 1, key_str, value_str);
|
71
|
+
"mdelem REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", md,
|
72
|
+
refcnt, refcnt + 1, key_str, value_str);
|
73
73
|
gpr_free(key_str);
|
74
74
|
gpr_free(value_str);
|
75
75
|
}
|
@@ -82,7 +82,7 @@ void grpc_mdelem_trace_unref(void* md, const grpc_slice& key,
|
|
82
82
|
char* key_str = grpc_slice_to_c_string(key);
|
83
83
|
char* value_str = grpc_slice_to_c_string(value);
|
84
84
|
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
85
|
-
"
|
85
|
+
"mdelem UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", md,
|
86
86
|
refcnt, refcnt - 1, key_str, value_str);
|
87
87
|
gpr_free(key_str);
|
88
88
|
gpr_free(value_str);
|
@@ -112,14 +112,33 @@ AllocatedMetadata::AllocatedMetadata(const grpc_slice& key,
|
|
112
112
|
: RefcountedMdBase(grpc_slice_ref_internal(key),
|
113
113
|
grpc_slice_ref_internal(value)) {
|
114
114
|
#ifndef NDEBUG
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
115
|
+
TraceAtStart("ALLOC_MD");
|
116
|
+
#endif
|
117
|
+
}
|
118
|
+
|
119
|
+
AllocatedMetadata::AllocatedMetadata(const grpc_slice& key,
|
120
|
+
const grpc_slice& value, const NoRefKey*)
|
121
|
+
: RefcountedMdBase(key, grpc_slice_ref_internal(value)) {
|
122
|
+
#ifndef NDEBUG
|
123
|
+
TraceAtStart("ALLOC_MD_NOREF_KEY");
|
124
|
+
#endif
|
125
|
+
}
|
126
|
+
|
127
|
+
AllocatedMetadata::AllocatedMetadata(
|
128
|
+
const grpc_core::ManagedMemorySlice& key,
|
129
|
+
const grpc_core::UnmanagedMemorySlice& value)
|
130
|
+
: RefcountedMdBase(key, value) {
|
131
|
+
#ifndef NDEBUG
|
132
|
+
TraceAtStart("ALLOC_MD_NOREF_KEY_VAL");
|
133
|
+
#endif
|
134
|
+
}
|
135
|
+
|
136
|
+
AllocatedMetadata::AllocatedMetadata(
|
137
|
+
const grpc_core::ExternallyManagedSlice& key,
|
138
|
+
const grpc_core::UnmanagedMemorySlice& value)
|
139
|
+
: RefcountedMdBase(key, value) {
|
140
|
+
#ifndef NDEBUG
|
141
|
+
TraceAtStart("ALLOC_MD_NOREF_KEY_VAL");
|
123
142
|
#endif
|
124
143
|
}
|
125
144
|
|
@@ -134,6 +153,19 @@ AllocatedMetadata::~AllocatedMetadata() {
|
|
134
153
|
}
|
135
154
|
}
|
136
155
|
|
156
|
+
#ifndef NDEBUG
|
157
|
+
void grpc_core::RefcountedMdBase::TraceAtStart(const char* tag) {
|
158
|
+
if (grpc_trace_metadata.enabled()) {
|
159
|
+
char* key_str = grpc_slice_to_c_string(key());
|
160
|
+
char* value_str = grpc_slice_to_c_string(value());
|
161
|
+
gpr_log(GPR_DEBUG, "mdelem %s:%p:%" PRIdPTR ": '%s' = '%s'", tag, this,
|
162
|
+
RefValue(), key_str, value_str);
|
163
|
+
gpr_free(key_str);
|
164
|
+
gpr_free(value_str);
|
165
|
+
}
|
166
|
+
}
|
167
|
+
#endif
|
168
|
+
|
137
169
|
InternedMetadata::InternedMetadata(const grpc_slice& key,
|
138
170
|
const grpc_slice& value, uint32_t hash,
|
139
171
|
InternedMetadata* next)
|
@@ -141,14 +173,16 @@ InternedMetadata::InternedMetadata(const grpc_slice& key,
|
|
141
173
|
grpc_slice_ref_internal(value), hash),
|
142
174
|
link_(next) {
|
143
175
|
#ifndef NDEBUG
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
176
|
+
TraceAtStart("INTERNED_MD");
|
177
|
+
#endif
|
178
|
+
}
|
179
|
+
|
180
|
+
InternedMetadata::InternedMetadata(const grpc_slice& key,
|
181
|
+
const grpc_slice& value, uint32_t hash,
|
182
|
+
InternedMetadata* next, const NoRefKey*)
|
183
|
+
: RefcountedMdBase(key, grpc_slice_ref_internal(value), hash), link_(next) {
|
184
|
+
#ifndef NDEBUG
|
185
|
+
TraceAtStart("INTERNED_MD_NOREF_KEY");
|
152
186
|
#endif
|
153
187
|
}
|
154
188
|
|
@@ -222,7 +256,12 @@ void grpc_mdctx_global_shutdown() {
|
|
222
256
|
abort();
|
223
257
|
}
|
224
258
|
}
|
259
|
+
// For ASAN builds, we don't want to crash here, because that will
|
260
|
+
// prevent ASAN from providing leak detection information, which is
|
261
|
+
// far more useful than this simple assertion.
|
262
|
+
#ifndef GRPC_ASAN_ENABLED
|
225
263
|
GPR_DEBUG_ASSERT(shard->count == 0);
|
264
|
+
#endif
|
226
265
|
gpr_free(shard->elems);
|
227
266
|
}
|
228
267
|
}
|
@@ -243,8 +282,8 @@ void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) {
|
|
243
282
|
char* value_str = grpc_slice_to_c_string(value());
|
244
283
|
intptr_t value = RefValue();
|
245
284
|
gpr_log(__FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG,
|
246
|
-
"
|
247
|
-
value + 1, key_str, value_str);
|
285
|
+
"mdelem REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", this,
|
286
|
+
value, value + 1, key_str, value_str);
|
248
287
|
gpr_free(key_str);
|
249
288
|
gpr_free(value_str);
|
250
289
|
}
|
@@ -302,36 +341,100 @@ static void rehash_mdtab(mdtab_shard* shard) {
|
|
302
341
|
}
|
303
342
|
}
|
304
343
|
|
305
|
-
|
344
|
+
template <bool key_definitely_static, bool value_definitely_static = false>
|
345
|
+
static grpc_mdelem md_create_maybe_static(const grpc_slice& key,
|
346
|
+
const grpc_slice& value);
|
347
|
+
template <bool key_definitely_static>
|
348
|
+
static grpc_mdelem md_create_must_intern(const grpc_slice& key,
|
349
|
+
const grpc_slice& value,
|
350
|
+
uint32_t hash);
|
351
|
+
|
352
|
+
template <bool key_definitely_static, bool value_definitely_static = false>
|
353
|
+
static grpc_mdelem md_create(
|
306
354
|
const grpc_slice& key, const grpc_slice& value,
|
307
355
|
grpc_mdelem_data* compatible_external_backing_store) {
|
356
|
+
// Ensure slices are, in fact, static if we claimed they were.
|
357
|
+
GPR_DEBUG_ASSERT(!key_definitely_static ||
|
358
|
+
GRPC_IS_STATIC_METADATA_STRING(key));
|
359
|
+
GPR_DEBUG_ASSERT(!value_definitely_static ||
|
360
|
+
GRPC_IS_STATIC_METADATA_STRING(value));
|
361
|
+
const bool key_is_interned =
|
362
|
+
key_definitely_static || grpc_slice_is_interned(key);
|
363
|
+
const bool value_is_interned =
|
364
|
+
value_definitely_static || grpc_slice_is_interned(value);
|
308
365
|
// External storage if either slice is not interned and the caller already
|
309
366
|
// created a backing store. If no backing store, we allocate one.
|
310
|
-
if (!
|
367
|
+
if (!key_is_interned || !value_is_interned) {
|
311
368
|
if (compatible_external_backing_store != nullptr) {
|
312
369
|
// Caller provided backing store.
|
313
370
|
return GRPC_MAKE_MDELEM(compatible_external_backing_store,
|
314
371
|
GRPC_MDELEM_STORAGE_EXTERNAL);
|
315
372
|
} else {
|
316
373
|
// We allocate backing store.
|
317
|
-
return
|
318
|
-
|
374
|
+
return key_definitely_static
|
375
|
+
? GRPC_MAKE_MDELEM(
|
376
|
+
grpc_core::New<AllocatedMetadata>(
|
377
|
+
key, value,
|
378
|
+
static_cast<const AllocatedMetadata::NoRefKey*>(
|
379
|
+
nullptr)),
|
380
|
+
GRPC_MDELEM_STORAGE_ALLOCATED)
|
381
|
+
: GRPC_MAKE_MDELEM(
|
382
|
+
grpc_core::New<AllocatedMetadata>(key, value),
|
383
|
+
GRPC_MDELEM_STORAGE_ALLOCATED);
|
319
384
|
}
|
320
385
|
}
|
386
|
+
return md_create_maybe_static<key_definitely_static, value_definitely_static>(
|
387
|
+
key, value);
|
388
|
+
}
|
389
|
+
|
390
|
+
template <bool key_definitely_static, bool value_definitely_static>
|
391
|
+
static grpc_mdelem md_create_maybe_static(const grpc_slice& key,
|
392
|
+
const grpc_slice& value) {
|
393
|
+
// Ensure slices are, in fact, static if we claimed they were.
|
394
|
+
GPR_DEBUG_ASSERT(!key_definitely_static ||
|
395
|
+
GRPC_IS_STATIC_METADATA_STRING(key));
|
396
|
+
GPR_DEBUG_ASSERT(!value_definitely_static ||
|
397
|
+
GRPC_IS_STATIC_METADATA_STRING(value));
|
398
|
+
GPR_DEBUG_ASSERT(key.refcount != nullptr);
|
399
|
+
GPR_DEBUG_ASSERT(value.refcount != nullptr);
|
400
|
+
|
401
|
+
const bool key_is_static_mdstr =
|
402
|
+
key_definitely_static ||
|
403
|
+
key.refcount->GetType() == grpc_slice_refcount::Type::STATIC;
|
404
|
+
const bool value_is_static_mdstr =
|
405
|
+
value_definitely_static ||
|
406
|
+
value.refcount->GetType() == grpc_slice_refcount::Type::STATIC;
|
407
|
+
|
408
|
+
const intptr_t kidx = GRPC_STATIC_METADATA_INDEX(key);
|
321
409
|
|
322
410
|
// Not all static slice input yields a statically stored metadata element.
|
323
|
-
|
324
|
-
if (GRPC_IS_STATIC_METADATA_STRING(key) &&
|
325
|
-
GRPC_IS_STATIC_METADATA_STRING(value)) {
|
411
|
+
if (key_is_static_mdstr && value_is_static_mdstr) {
|
326
412
|
grpc_mdelem static_elem = grpc_static_mdelem_for_static_strings(
|
327
|
-
|
413
|
+
kidx, GRPC_STATIC_METADATA_INDEX(value));
|
328
414
|
if (!GRPC_MDISNULL(static_elem)) {
|
329
415
|
return static_elem;
|
330
416
|
}
|
331
417
|
}
|
332
418
|
|
333
|
-
uint32_t
|
334
|
-
|
419
|
+
uint32_t khash = key_definitely_static
|
420
|
+
? grpc_static_metadata_hash_values[kidx]
|
421
|
+
: grpc_slice_hash_refcounted(key);
|
422
|
+
|
423
|
+
uint32_t hash = GRPC_MDSTR_KV_HASH(khash, grpc_slice_hash_refcounted(value));
|
424
|
+
return md_create_must_intern<key_definitely_static>(key, value, hash);
|
425
|
+
}
|
426
|
+
|
427
|
+
template <bool key_definitely_static>
|
428
|
+
static grpc_mdelem md_create_must_intern(const grpc_slice& key,
|
429
|
+
const grpc_slice& value,
|
430
|
+
uint32_t hash) {
|
431
|
+
// Here, we know both key and value are both at least interned, and both
|
432
|
+
// possibly static. We know that anything inside the shared interned table is
|
433
|
+
// also at least interned (and maybe static). Note that equality for a static
|
434
|
+
// and interned slice implies that they are both the same exact slice.
|
435
|
+
// The same applies to a pair of interned slices, or a pair of static slices.
|
436
|
+
// Rather than run the full equality check, we can therefore just do a pointer
|
437
|
+
// comparison of the refcounts.
|
335
438
|
InternedMetadata* md;
|
336
439
|
mdtab_shard* shard = &g_shards[SHARD_IDX(hash)];
|
337
440
|
size_t idx;
|
@@ -343,7 +446,8 @@ grpc_mdelem grpc_mdelem_create(
|
|
343
446
|
idx = TABLE_IDX(hash, shard->capacity);
|
344
447
|
/* search for an existing pair */
|
345
448
|
for (md = shard->elems[idx].next; md; md = md->bucket_next()) {
|
346
|
-
if (
|
449
|
+
if (grpc_slice_static_interned_equal(key, md->key()) &&
|
450
|
+
grpc_slice_static_interned_equal(value, md->value())) {
|
347
451
|
md->RefWithShardLocked(shard);
|
348
452
|
gpr_mu_unlock(&shard->mu);
|
349
453
|
return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
|
@@ -351,8 +455,12 @@ grpc_mdelem grpc_mdelem_create(
|
|
351
455
|
}
|
352
456
|
|
353
457
|
/* not found: create a new pair */
|
354
|
-
md =
|
355
|
-
|
458
|
+
md = key_definitely_static
|
459
|
+
? grpc_core::New<InternedMetadata>(
|
460
|
+
key, value, hash, shard->elems[idx].next,
|
461
|
+
static_cast<const InternedMetadata::NoRefKey*>(nullptr))
|
462
|
+
: grpc_core::New<InternedMetadata>(key, value, hash,
|
463
|
+
shard->elems[idx].next);
|
356
464
|
shard->elems[idx].next = md;
|
357
465
|
shard->count++;
|
358
466
|
|
@@ -365,9 +473,68 @@ grpc_mdelem grpc_mdelem_create(
|
|
365
473
|
return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
|
366
474
|
}
|
367
475
|
|
476
|
+
grpc_mdelem grpc_mdelem_create(
|
477
|
+
const grpc_slice& key, const grpc_slice& value,
|
478
|
+
grpc_mdelem_data* compatible_external_backing_store) {
|
479
|
+
return md_create<false>(key, value, compatible_external_backing_store);
|
480
|
+
}
|
481
|
+
|
482
|
+
grpc_mdelem grpc_mdelem_create(
|
483
|
+
const grpc_core::StaticMetadataSlice& key, const grpc_slice& value,
|
484
|
+
grpc_mdelem_data* compatible_external_backing_store) {
|
485
|
+
return md_create<true>(key, value, compatible_external_backing_store);
|
486
|
+
}
|
487
|
+
|
488
|
+
/* Create grpc_mdelem from provided slices. We specify via template parameter
|
489
|
+
whether we know that the input key is static or not. If it is, we short
|
490
|
+
circuit various comparisons and a no-op unref. */
|
491
|
+
template <bool key_definitely_static>
|
492
|
+
static grpc_mdelem md_from_slices(const grpc_slice& key,
|
493
|
+
const grpc_slice& value) {
|
494
|
+
// Ensure key is, in fact, static if we claimed it was.
|
495
|
+
GPR_DEBUG_ASSERT(!key_definitely_static ||
|
496
|
+
GRPC_IS_STATIC_METADATA_STRING(key));
|
497
|
+
grpc_mdelem out = md_create<key_definitely_static>(key, value, nullptr);
|
498
|
+
if (!key_definitely_static) {
|
499
|
+
grpc_slice_unref_internal(key);
|
500
|
+
}
|
501
|
+
grpc_slice_unref_internal(value);
|
502
|
+
return out;
|
503
|
+
}
|
504
|
+
|
368
505
|
grpc_mdelem grpc_mdelem_from_slices(const grpc_slice& key,
|
369
506
|
const grpc_slice& value) {
|
370
|
-
|
507
|
+
return md_from_slices</*key_definitely_static=*/false>(key, value);
|
508
|
+
}
|
509
|
+
|
510
|
+
grpc_mdelem grpc_mdelem_from_slices(const grpc_core::StaticMetadataSlice& key,
|
511
|
+
const grpc_slice& value) {
|
512
|
+
return md_from_slices</*key_definitely_static=*/true>(key, value);
|
513
|
+
}
|
514
|
+
|
515
|
+
grpc_mdelem grpc_mdelem_from_slices(
|
516
|
+
const grpc_core::StaticMetadataSlice& key,
|
517
|
+
const grpc_core::StaticMetadataSlice& value) {
|
518
|
+
grpc_mdelem out = md_create_maybe_static<true, true>(key, value);
|
519
|
+
return out;
|
520
|
+
}
|
521
|
+
|
522
|
+
grpc_mdelem grpc_mdelem_from_slices(
|
523
|
+
const grpc_core::StaticMetadataSlice& key,
|
524
|
+
const grpc_core::ManagedMemorySlice& value) {
|
525
|
+
// TODO(arjunroy): We can save the unref if md_create_maybe_static ended up
|
526
|
+
// creating a new interned metadata. But otherwise - we need this here.
|
527
|
+
grpc_mdelem out = md_create_maybe_static<true>(key, value);
|
528
|
+
grpc_slice_unref_internal(value);
|
529
|
+
return out;
|
530
|
+
}
|
531
|
+
|
532
|
+
grpc_mdelem grpc_mdelem_from_slices(
|
533
|
+
const grpc_core::ManagedMemorySlice& key,
|
534
|
+
const grpc_core::ManagedMemorySlice& value) {
|
535
|
+
grpc_mdelem out = md_create_maybe_static<false>(key, value);
|
536
|
+
// TODO(arjunroy): We can save the unref if md_create_maybe_static ended up
|
537
|
+
// creating a new interned metadata. But otherwise - we need this here.
|
371
538
|
grpc_slice_unref_internal(key);
|
372
539
|
grpc_slice_unref_internal(value);
|
373
540
|
return out;
|
@@ -118,10 +118,31 @@ struct grpc_mdelem {
|
|
118
118
|
((grpc_mdelem_data_storage)((md).payload & \
|
119
119
|
(uintptr_t)GRPC_MDELEM_STORAGE_INTERNED_BIT))
|
120
120
|
|
121
|
-
/*
|
121
|
+
/* Given arbitrary input slices, create a grpc_mdelem object. The caller refs
|
122
|
+
* the input slices; we unref them. This method is always safe to call; however,
|
123
|
+
* if we know data about the slices in question (e.g. if we knew our key was
|
124
|
+
* static) we can call specializations that save on cycle count. */
|
122
125
|
grpc_mdelem grpc_mdelem_from_slices(const grpc_slice& key,
|
123
126
|
const grpc_slice& value);
|
124
127
|
|
128
|
+
/* Like grpc_mdelem_from_slices, but we know that key is a static slice. This
|
129
|
+
saves us a few branches and a no-op call to md_unref() for the key. */
|
130
|
+
grpc_mdelem grpc_mdelem_from_slices(const grpc_core::StaticMetadataSlice& key,
|
131
|
+
const grpc_slice& value);
|
132
|
+
|
133
|
+
/* Like grpc_mdelem_from_slices, but key is static and val is static. */
|
134
|
+
grpc_mdelem grpc_mdelem_from_slices(
|
135
|
+
const grpc_core::StaticMetadataSlice& key,
|
136
|
+
const grpc_core::StaticMetadataSlice& value);
|
137
|
+
|
138
|
+
/* Like grpc_mdelem_from_slices, but key is static and val is interned. */
|
139
|
+
grpc_mdelem grpc_mdelem_from_slices(const grpc_core::StaticMetadataSlice& key,
|
140
|
+
const grpc_core::ManagedMemorySlice& value);
|
141
|
+
|
142
|
+
/* Like grpc_mdelem_from_slices, but key and val are interned. */
|
143
|
+
grpc_mdelem grpc_mdelem_from_slices(const grpc_core::ManagedMemorySlice& key,
|
144
|
+
const grpc_core::ManagedMemorySlice& value);
|
145
|
+
|
125
146
|
/* Cheaply convert a grpc_metadata to a grpc_mdelem; may use the grpc_metadata
|
126
147
|
object as backing storage (so lifetimes should align) */
|
127
148
|
grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata);
|
@@ -134,6 +155,11 @@ grpc_mdelem grpc_mdelem_create(
|
|
134
155
|
const grpc_slice& key, const grpc_slice& value,
|
135
156
|
grpc_mdelem_data* compatible_external_backing_store);
|
136
157
|
|
158
|
+
/* Like grpc_mdelem_create, but we know that key is static. */
|
159
|
+
grpc_mdelem grpc_mdelem_create(
|
160
|
+
const grpc_core::StaticMetadataSlice& key, const grpc_slice& value,
|
161
|
+
grpc_mdelem_data* compatible_external_backing_store);
|
162
|
+
|
137
163
|
#define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key)
|
138
164
|
#define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value)
|
139
165
|
|
@@ -186,19 +212,21 @@ struct UserData {
|
|
186
212
|
|
187
213
|
class StaticMetadata {
|
188
214
|
public:
|
189
|
-
StaticMetadata(const grpc_slice& key, const grpc_slice& value)
|
190
|
-
: kv_({key, value}), hash_(0) {}
|
215
|
+
StaticMetadata(const grpc_slice& key, const grpc_slice& value, uintptr_t idx)
|
216
|
+
: kv_({key, value}), hash_(0), static_idx_(idx) {}
|
191
217
|
|
192
218
|
const grpc_mdelem_data& data() const { return kv_; }
|
193
219
|
|
194
220
|
void HashInit();
|
195
221
|
uint32_t hash() { return hash_; }
|
222
|
+
uintptr_t StaticIndex() { return static_idx_; }
|
196
223
|
|
197
224
|
private:
|
198
225
|
grpc_mdelem_data kv_;
|
199
226
|
|
200
227
|
/* private only data */
|
201
228
|
uint32_t hash_;
|
229
|
+
uintptr_t static_idx_;
|
202
230
|
};
|
203
231
|
|
204
232
|
class RefcountedMdBase {
|
@@ -237,6 +265,10 @@ class RefcountedMdBase {
|
|
237
265
|
}
|
238
266
|
|
239
267
|
protected:
|
268
|
+
#ifndef NDEBUG
|
269
|
+
void TraceAtStart(const char* tag);
|
270
|
+
#endif
|
271
|
+
|
240
272
|
intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); }
|
241
273
|
bool AllRefsDropped() { return refcnt_.Load(MemoryOrder::ACQUIRE) == 0; }
|
242
274
|
bool FirstRef() { return refcnt_.FetchAdd(1, MemoryOrder::RELAXED) == 0; }
|
@@ -251,16 +283,19 @@ class RefcountedMdBase {
|
|
251
283
|
|
252
284
|
class InternedMetadata : public RefcountedMdBase {
|
253
285
|
public:
|
286
|
+
// TODO(arjunroy): Change to use strongly typed slices instead.
|
287
|
+
struct NoRefKey {};
|
254
288
|
struct BucketLink {
|
255
289
|
explicit BucketLink(InternedMetadata* md) : next(md) {}
|
256
290
|
|
257
291
|
InternedMetadata* next = nullptr;
|
258
292
|
};
|
259
|
-
|
260
293
|
InternedMetadata(const grpc_slice& key, const grpc_slice& value,
|
261
294
|
uint32_t hash, InternedMetadata* next);
|
262
|
-
|
295
|
+
InternedMetadata(const grpc_slice& key, const grpc_slice& value,
|
296
|
+
uint32_t hash, InternedMetadata* next, const NoRefKey*);
|
263
297
|
|
298
|
+
~InternedMetadata();
|
264
299
|
void RefWithShardLocked(mdtab_shard* shard);
|
265
300
|
UserData* user_data() { return &user_data_; }
|
266
301
|
InternedMetadata* bucket_next() { return link_.next; }
|
@@ -276,7 +311,15 @@ class InternedMetadata : public RefcountedMdBase {
|
|
276
311
|
/* Shadow structure for grpc_mdelem_data for allocated elements */
|
277
312
|
class AllocatedMetadata : public RefcountedMdBase {
|
278
313
|
public:
|
314
|
+
// TODO(arjunroy): Change to use strongly typed slices instead.
|
315
|
+
struct NoRefKey {};
|
279
316
|
AllocatedMetadata(const grpc_slice& key, const grpc_slice& value);
|
317
|
+
AllocatedMetadata(const grpc_core::ManagedMemorySlice& key,
|
318
|
+
const grpc_core::UnmanagedMemorySlice& value);
|
319
|
+
AllocatedMetadata(const grpc_core::ExternallyManagedSlice& key,
|
320
|
+
const grpc_core::UnmanagedMemorySlice& value);
|
321
|
+
AllocatedMetadata(const grpc_slice& key, const grpc_slice& value,
|
322
|
+
const NoRefKey*);
|
280
323
|
~AllocatedMetadata();
|
281
324
|
|
282
325
|
UserData* user_data() { return &user_data_; }
|
@@ -348,10 +391,11 @@ inline void grpc_mdelem_unref(grpc_mdelem gmd) {
|
|
348
391
|
free an interned md at any time: it's unsafe from this point on to
|
349
392
|
access it so we read the hash now. */
|
350
393
|
uint32_t hash = md->hash();
|
351
|
-
if (GPR_UNLIKELY(md->Unref())) {
|
352
394
|
#ifndef NDEBUG
|
395
|
+
if (GPR_UNLIKELY(md->Unref(file, line))) {
|
353
396
|
grpc_mdelem_on_final_unref(storage, md, hash, file, line);
|
354
397
|
#else
|
398
|
+
if (GPR_UNLIKELY(md->Unref())) {
|
355
399
|
grpc_mdelem_on_final_unref(storage, md, hash);
|
356
400
|
#endif
|
357
401
|
}
|
@@ -371,4 +415,35 @@ inline void grpc_mdelem_unref(grpc_mdelem gmd) {
|
|
371
415
|
void grpc_mdctx_global_init(void);
|
372
416
|
void grpc_mdctx_global_shutdown();
|
373
417
|
|
418
|
+
/* Like grpc_mdelem_from_slices, but we know that key is a static or interned
|
419
|
+
slice and value is not static or interned. This gives us an inlinable
|
420
|
+
fastpath - we know we must allocate metadata now, and that we do not need to
|
421
|
+
unref the value (rather, we just transfer the ref). We can avoid a ref since:
|
422
|
+
1) the key slice is passed in already ref'd
|
423
|
+
2) We're guaranteed to create a new Allocated slice, thus meaning the
|
424
|
+
ref can be considered 'transferred'.*/
|
425
|
+
inline grpc_mdelem grpc_mdelem_from_slices(
|
426
|
+
const grpc_core::ManagedMemorySlice& key,
|
427
|
+
const grpc_core::UnmanagedMemorySlice& value) {
|
428
|
+
using grpc_core::AllocatedMetadata;
|
429
|
+
return GRPC_MAKE_MDELEM(grpc_core::New<AllocatedMetadata>(key, value),
|
430
|
+
GRPC_MDELEM_STORAGE_ALLOCATED);
|
431
|
+
}
|
432
|
+
|
433
|
+
inline grpc_mdelem grpc_mdelem_from_slices(
|
434
|
+
const grpc_core::ExternallyManagedSlice& key,
|
435
|
+
const grpc_core::UnmanagedMemorySlice& value) {
|
436
|
+
using grpc_core::AllocatedMetadata;
|
437
|
+
return GRPC_MAKE_MDELEM(grpc_core::New<AllocatedMetadata>(key, value),
|
438
|
+
GRPC_MDELEM_STORAGE_ALLOCATED);
|
439
|
+
}
|
440
|
+
|
441
|
+
inline grpc_mdelem grpc_mdelem_from_slices(
|
442
|
+
const grpc_core::StaticMetadataSlice& key,
|
443
|
+
const grpc_core::UnmanagedMemorySlice& value) {
|
444
|
+
using grpc_core::AllocatedMetadata;
|
445
|
+
return GRPC_MAKE_MDELEM(grpc_core::New<AllocatedMetadata>(key, value),
|
446
|
+
GRPC_MDELEM_STORAGE_ALLOCATED);
|
447
|
+
}
|
448
|
+
|
374
449
|
#endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */
|