grpc 1.20.0 → 1.21.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 +500 -29
- data/etc/roots.pem +146 -0
- data/include/grpc/grpc_security.h +1 -1
- data/include/grpc/impl/codegen/grpc_types.h +10 -7
- data/include/grpc/impl/codegen/port_platform.h +11 -1
- data/include/grpc/impl/codegen/slice.h +1 -21
- data/include/grpc/impl/codegen/status.h +2 -1
- data/include/grpc/slice.h +1 -1
- data/src/core/ext/filters/client_channel/backup_poller.cc +19 -13
- data/src/core/ext/filters/client_channel/backup_poller.h +3 -0
- data/src/core/ext/filters/client_channel/channel_connectivity.cc +1 -1
- data/src/core/ext/filters/client_channel/client_channel.cc +2084 -1673
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +2 -3
- data/src/core/ext/filters/client_channel/client_channel_plugin.cc +4 -0
- data/src/core/ext/filters/client_channel/health/health_check_client.cc +54 -49
- data/src/core/ext/filters/client_channel/health/health_check_client.h +20 -9
- data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -2
- data/src/core/ext/filters/client_channel/http_connect_handshaker.h +1 -1
- data/src/core/ext/filters/client_channel/lb_policy.cc +3 -30
- data/src/core/ext/filters/client_channel/lb_policy.h +16 -25
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +106 -81
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +6 -2
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +8 -12
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +2 -2
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +1 -1
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +57 -49
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +47 -41
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +24 -20
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +989 -284
- data/src/core/ext/filters/client_channel/lb_policy_factory.h +4 -1
- data/src/core/ext/filters/client_channel/lb_policy_registry.cc +105 -2
- data/src/core/ext/filters/client_channel/lb_policy_registry.h +9 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +79 -36
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +84 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +3 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +179 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +15 -3
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +80 -4
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +7 -13
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +2 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +39 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +0 -6
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +2 -64
- data/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc +28 -0
- data/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h +29 -0
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +4 -4
- data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +367 -232
- data/src/core/ext/filters/client_channel/resolver_result_parsing.h +55 -76
- data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +50 -39
- data/src/core/ext/filters/client_channel/resolving_lb_policy.h +18 -12
- data/src/core/ext/filters/client_channel/service_config.cc +247 -27
- data/src/core/ext/filters/client_channel/service_config.h +119 -166
- data/src/core/ext/filters/client_channel/subchannel.cc +46 -84
- data/src/core/ext/filters/client_channel/subchannel.h +7 -7
- data/src/core/ext/filters/deadline/deadline_filter.cc +3 -4
- data/src/core/ext/filters/deadline/deadline_filter.h +3 -2
- data/src/core/ext/filters/http/client/http_client_filter.cc +7 -5
- data/src/core/ext/filters/http/client/http_client_filter.h +1 -1
- data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +4 -3
- data/src/core/ext/filters/http/server/http_server_filter.cc +18 -12
- data/src/core/ext/filters/message_size/message_size_filter.cc +118 -76
- data/src/core/ext/filters/message_size/message_size_filter.h +33 -0
- data/src/core/ext/transport/chttp2/alpn/alpn.h +1 -1
- data/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +9 -7
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +93 -60
- data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +4 -3
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +3 -3
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +8 -2
- data/src/core/ext/transport/chttp2/transport/hpack_table.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +3 -2
- data/src/core/ext/transport/chttp2/transport/internal.h +35 -23
- data/src/core/ext/transport/chttp2/transport/parsing.cc +4 -4
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +3 -3
- data/src/core/ext/transport/chttp2/transport/writing.cc +61 -27
- data/src/core/ext/transport/inproc/inproc_transport.cc +18 -18
- data/src/core/lib/channel/channel_args.cc +0 -101
- data/src/core/lib/channel/channel_args.h +0 -37
- data/src/core/lib/channel/channel_stack.h +9 -5
- data/src/core/lib/channel/channelz_registry.cc +1 -1
- data/src/core/lib/channel/connected_channel.cc +2 -2
- data/src/core/lib/channel/context.h +3 -0
- data/src/core/lib/channel/handshaker.cc +4 -4
- data/src/core/lib/channel/handshaker.h +1 -1
- data/src/core/lib/compression/compression_args.cc +127 -0
- data/src/core/lib/compression/compression_args.h +55 -0
- data/src/core/lib/debug/trace.cc +13 -7
- data/src/core/lib/debug/trace.h +12 -0
- data/src/core/lib/gpr/arena.h +13 -9
- data/src/core/lib/gpr/env.h +2 -5
- data/src/core/lib/gpr/env_linux.cc +6 -1
- data/src/core/lib/gpr/env_posix.cc +5 -0
- data/src/core/lib/gpr/env_windows.cc +7 -5
- data/src/core/lib/gpr/log.cc +9 -13
- data/src/core/lib/gpr/string.cc +12 -6
- data/src/core/lib/gpr/string.h +4 -2
- data/src/core/lib/gpr/time_posix.cc +13 -0
- data/src/core/lib/gprpp/arena.cc +103 -0
- data/src/core/lib/gprpp/arena.h +121 -0
- data/src/core/lib/gprpp/fork.cc +12 -29
- data/src/core/lib/gprpp/global_config.h +87 -0
- data/src/core/lib/gprpp/global_config_custom.h +29 -0
- data/src/core/lib/gprpp/global_config_env.cc +135 -0
- data/src/core/lib/gprpp/global_config_env.h +131 -0
- data/src/core/lib/gprpp/global_config_generic.h +44 -0
- data/src/core/lib/gprpp/map.h +419 -0
- data/src/core/lib/gprpp/optional.h +1 -0
- data/src/core/lib/gprpp/orphanable.h +2 -2
- data/src/core/lib/gprpp/{mutex_lock.h → pair.h} +15 -19
- data/src/core/lib/gprpp/ref_counted.h +18 -2
- data/src/core/lib/gprpp/sync.h +126 -0
- data/src/core/lib/http/parser.cc +1 -1
- data/src/core/lib/iomgr/call_combiner.cc +84 -90
- data/src/core/lib/iomgr/call_combiner.h +75 -82
- data/src/core/lib/iomgr/cfstream_handle.cc +202 -0
- data/src/core/lib/iomgr/cfstream_handle.h +82 -0
- data/src/core/lib/iomgr/combiner.h +1 -1
- data/src/core/lib/iomgr/endpoint_cfstream.cc +375 -0
- data/src/core/lib/iomgr/endpoint_cfstream.h +49 -0
- data/src/core/lib/iomgr/endpoint_pair_windows.cc +2 -2
- data/src/core/lib/iomgr/error.h +23 -0
- data/src/core/lib/iomgr/error_cfstream.cc +52 -0
- data/src/core/lib/iomgr/error_cfstream.h +31 -0
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +34 -27
- data/src/core/lib/iomgr/ev_epollex_linux.cc +33 -33
- data/src/core/lib/iomgr/ev_poll_posix.cc +7 -7
- data/src/core/lib/iomgr/ev_posix.cc +15 -13
- data/src/core/lib/iomgr/ev_posix.h +4 -1
- data/src/core/lib/iomgr/executor.cc +13 -9
- data/src/core/lib/iomgr/fork_posix.cc +0 -1
- data/src/core/lib/iomgr/internal_errqueue.cc +1 -1
- data/src/core/lib/iomgr/iomgr.cc +6 -5
- data/src/core/lib/iomgr/iomgr_custom.cc +3 -0
- data/src/core/lib/iomgr/iomgr_custom.h +2 -0
- data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +93 -0
- data/src/core/lib/iomgr/iomgr_windows.cc +1 -0
- data/src/core/lib/iomgr/lockfree_event.cc +3 -3
- data/src/core/lib/iomgr/port.h +11 -0
- data/src/core/lib/iomgr/resource_quota.cc +40 -37
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +6 -2
- data/src/core/lib/iomgr/socket_windows.cc +19 -0
- data/src/core/lib/iomgr/socket_windows.h +8 -0
- data/src/core/lib/iomgr/tcp_client_cfstream.cc +216 -0
- data/src/core/lib/iomgr/tcp_client_custom.cc +2 -2
- data/src/core/lib/iomgr/tcp_client_posix.cc +3 -3
- data/src/core/lib/iomgr/tcp_client_windows.cc +1 -1
- data/src/core/lib/iomgr/tcp_custom.cc +9 -9
- data/src/core/lib/iomgr/tcp_posix.cc +41 -41
- data/src/core/lib/iomgr/tcp_server_custom.cc +3 -3
- data/src/core/lib/iomgr/tcp_server_posix.cc +14 -1
- data/src/core/lib/iomgr/tcp_server_windows.cc +2 -2
- data/src/core/lib/iomgr/tcp_windows.cc +7 -9
- data/src/core/lib/iomgr/timer_generic.cc +16 -16
- data/src/core/lib/iomgr/timer_manager.cc +12 -11
- data/src/core/lib/profiling/basic_timers.cc +10 -4
- data/src/core/lib/security/context/security_context.cc +6 -7
- data/src/core/lib/security/context/security_context.h +3 -4
- data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +1 -1
- data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +2 -3
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -1
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +7 -7
- data/src/core/lib/security/security_connector/load_system_roots_linux.cc +7 -5
- data/src/core/lib/security/security_connector/security_connector.cc +0 -1
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +3 -2
- data/src/core/lib/security/security_connector/ssl_utils.cc +30 -26
- data/src/core/lib/security/security_connector/ssl_utils.h +5 -1
- data/src/core/lib/security/transport/client_auth_filter.cc +7 -11
- data/src/core/lib/security/transport/secure_endpoint.cc +4 -4
- data/src/core/lib/security/transport/server_auth_filter.cc +2 -3
- data/src/core/lib/slice/slice.cc +99 -116
- data/src/core/lib/slice/slice_buffer.cc +5 -0
- data/src/core/lib/slice/slice_intern.cc +38 -95
- data/src/core/lib/slice/slice_internal.h +200 -2
- data/src/core/lib/surface/api_trace.h +1 -1
- data/src/core/lib/surface/call.cc +41 -35
- data/src/core/lib/surface/call.h +7 -2
- data/src/core/lib/surface/call_details.cc +0 -1
- data/src/core/lib/surface/completion_queue.cc +36 -27
- data/src/core/lib/surface/init.cc +3 -4
- data/src/core/lib/surface/lame_client.cc +1 -1
- data/src/core/lib/surface/server.cc +18 -25
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/lib/transport/bdp_estimator.cc +3 -3
- data/src/core/lib/transport/bdp_estimator.h +2 -2
- data/src/core/lib/transport/connectivity_state.cc +10 -40
- data/src/core/lib/transport/connectivity_state.h +0 -8
- data/src/core/lib/transport/error_utils.cc +12 -0
- data/src/core/lib/transport/metadata.cc +206 -278
- data/src/core/lib/transport/metadata.h +205 -10
- data/src/core/lib/transport/static_metadata.cc +108 -116
- data/src/core/lib/transport/static_metadata.h +1 -2
- data/src/core/lib/transport/status_metadata.cc +3 -3
- data/src/core/lib/transport/transport.cc +29 -66
- data/src/core/lib/transport/transport.h +36 -8
- data/src/core/lib/transport/transport_impl.h +1 -1
- data/src/core/tsi/fake_transport_security.cc +4 -4
- data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +1 -1
- data/src/core/tsi/ssl_transport_security.cc +1 -1
- data/src/ruby/ext/grpc/rb_grpc.c +1 -1
- data/src/ruby/lib/grpc/errors.rb +22 -3
- data/src/ruby/lib/grpc/generic/bidi_call.rb +1 -1
- data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/errors_spec.rb +141 -0
- metadata +57 -33
- data/src/core/lib/gpr/arena.cc +0 -192
@@ -33,6 +33,10 @@
|
|
33
33
|
#define GROW(x) (3 * (x) / 2)
|
34
34
|
|
35
35
|
static void maybe_embiggen(grpc_slice_buffer* sb) {
|
36
|
+
if (sb->count == 0) {
|
37
|
+
sb->slices = sb->base_slices;
|
38
|
+
}
|
39
|
+
|
36
40
|
/* How far away from sb->base_slices is sb->slices pointer */
|
37
41
|
size_t slice_offset = static_cast<size_t>(sb->slices - sb->base_slices);
|
38
42
|
size_t slice_count = sb->count + slice_offset;
|
@@ -177,6 +181,7 @@ void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer* sb) {
|
|
177
181
|
|
178
182
|
sb->count = 0;
|
179
183
|
sb->length = 0;
|
184
|
+
sb->slices = sb->base_slices;
|
180
185
|
}
|
181
186
|
|
182
187
|
void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer* sb) {
|
@@ -27,6 +27,7 @@
|
|
27
27
|
#include <grpc/support/log.h>
|
28
28
|
|
29
29
|
#include "src/core/lib/gpr/murmur_hash.h"
|
30
|
+
#include "src/core/lib/gprpp/sync.h"
|
30
31
|
#include "src/core/lib/iomgr/iomgr_internal.h" /* for iomgr_abort_on_leaks() */
|
31
32
|
#include "src/core/lib/profiling/timers.h"
|
32
33
|
#include "src/core/lib/slice/slice_string_helpers.h"
|
@@ -39,24 +40,17 @@
|
|
39
40
|
#define TABLE_IDX(hash, capacity) (((hash) >> LOG2_SHARD_COUNT) % (capacity))
|
40
41
|
#define SHARD_IDX(hash) ((hash) & ((1 << LOG2_SHARD_COUNT) - 1))
|
41
42
|
|
42
|
-
|
43
|
-
grpc_slice_refcount base;
|
44
|
-
grpc_slice_refcount sub;
|
45
|
-
size_t length;
|
46
|
-
gpr_atm refcnt;
|
47
|
-
uint32_t hash;
|
48
|
-
struct interned_slice_refcount* bucket_next;
|
49
|
-
} interned_slice_refcount;
|
43
|
+
using grpc_core::InternedSliceRefcount;
|
50
44
|
|
51
45
|
typedef struct slice_shard {
|
52
46
|
gpr_mu mu;
|
53
|
-
|
47
|
+
InternedSliceRefcount** strs;
|
54
48
|
size_t count;
|
55
49
|
size_t capacity;
|
56
50
|
} slice_shard;
|
57
51
|
|
58
52
|
/* hash seed: decided at initialization time */
|
59
|
-
|
53
|
+
uint32_t g_hash_seed;
|
60
54
|
static int g_forced_hash_seed = 0;
|
61
55
|
|
62
56
|
static slice_shard g_shards[SHARD_COUNT];
|
@@ -69,73 +63,35 @@ typedef struct {
|
|
69
63
|
static static_metadata_hash_ent
|
70
64
|
static_metadata_hash[4 * GRPC_STATIC_MDSTR_COUNT];
|
71
65
|
static uint32_t max_static_metadata_hash_probe;
|
72
|
-
|
66
|
+
uint32_t grpc_static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT];
|
73
67
|
|
74
|
-
|
75
|
-
interned_slice_refcount* s = static_cast<interned_slice_refcount*>(p);
|
76
|
-
GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) > 0);
|
77
|
-
}
|
68
|
+
namespace grpc_core {
|
78
69
|
|
79
|
-
|
80
|
-
slice_shard* shard = &g_shards[SHARD_IDX(
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
for (prev_next = &shard->strs[TABLE_IDX(s->hash, shard->capacity)],
|
70
|
+
InternedSliceRefcount::~InternedSliceRefcount() {
|
71
|
+
slice_shard* shard = &g_shards[SHARD_IDX(this->hash)];
|
72
|
+
MutexLock lock(&shard->mu);
|
73
|
+
InternedSliceRefcount** prev_next;
|
74
|
+
InternedSliceRefcount* cur;
|
75
|
+
for (prev_next = &shard->strs[TABLE_IDX(this->hash, shard->capacity)],
|
86
76
|
cur = *prev_next;
|
87
|
-
cur !=
|
77
|
+
cur != this; prev_next = &cur->bucket_next, cur = cur->bucket_next)
|
88
78
|
;
|
89
79
|
*prev_next = cur->bucket_next;
|
90
80
|
shard->count--;
|
91
|
-
gpr_free(s);
|
92
|
-
gpr_mu_unlock(&shard->mu);
|
93
|
-
}
|
94
|
-
|
95
|
-
static void interned_slice_unref(void* p) {
|
96
|
-
interned_slice_refcount* s = static_cast<interned_slice_refcount*>(p);
|
97
|
-
if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) {
|
98
|
-
interned_slice_destroy(s);
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
static void interned_slice_sub_ref(void* p) {
|
103
|
-
interned_slice_ref((static_cast<char*>(p)) -
|
104
|
-
offsetof(interned_slice_refcount, sub));
|
105
|
-
}
|
106
|
-
|
107
|
-
static void interned_slice_sub_unref(void* p) {
|
108
|
-
interned_slice_unref((static_cast<char*>(p)) -
|
109
|
-
offsetof(interned_slice_refcount, sub));
|
110
|
-
}
|
111
|
-
|
112
|
-
static uint32_t interned_slice_hash(grpc_slice slice) {
|
113
|
-
interned_slice_refcount* s =
|
114
|
-
reinterpret_cast<interned_slice_refcount*>(slice.refcount);
|
115
|
-
return s->hash;
|
116
|
-
}
|
117
|
-
|
118
|
-
static int interned_slice_eq(grpc_slice a, grpc_slice b) {
|
119
|
-
return a.refcount == b.refcount;
|
120
81
|
}
|
121
82
|
|
122
|
-
|
123
|
-
interned_slice_ref, interned_slice_unref, interned_slice_eq,
|
124
|
-
interned_slice_hash};
|
125
|
-
static const grpc_slice_refcount_vtable interned_slice_sub_vtable = {
|
126
|
-
interned_slice_sub_ref, interned_slice_sub_unref,
|
127
|
-
grpc_slice_default_eq_impl, grpc_slice_default_hash_impl};
|
83
|
+
} // namespace grpc_core
|
128
84
|
|
129
85
|
static void grow_shard(slice_shard* shard) {
|
130
86
|
GPR_TIMER_SCOPE("grow_strtab", 0);
|
131
87
|
|
132
88
|
size_t capacity = shard->capacity * 2;
|
133
89
|
size_t i;
|
134
|
-
|
135
|
-
|
90
|
+
InternedSliceRefcount** strtab;
|
91
|
+
InternedSliceRefcount *s, *next;
|
136
92
|
|
137
|
-
strtab = static_cast<
|
138
|
-
gpr_zalloc(sizeof(
|
93
|
+
strtab = static_cast<InternedSliceRefcount**>(
|
94
|
+
gpr_zalloc(sizeof(InternedSliceRefcount*) * capacity));
|
139
95
|
|
140
96
|
for (i = 0; i < shard->capacity; i++) {
|
141
97
|
for (s = shard->strs[i]; s; s = next) {
|
@@ -150,7 +106,7 @@ static void grow_shard(slice_shard* shard) {
|
|
150
106
|
shard->capacity = capacity;
|
151
107
|
}
|
152
108
|
|
153
|
-
static grpc_slice materialize(
|
109
|
+
static grpc_slice materialize(InternedSliceRefcount* s) {
|
154
110
|
grpc_slice slice;
|
155
111
|
slice.refcount = &s->base;
|
156
112
|
slice.data.refcounted.bytes = reinterpret_cast<uint8_t*>(s + 1);
|
@@ -164,7 +120,7 @@ uint32_t grpc_slice_default_hash_impl(grpc_slice s) {
|
|
164
120
|
}
|
165
121
|
|
166
122
|
uint32_t grpc_static_slice_hash(grpc_slice s) {
|
167
|
-
return
|
123
|
+
return grpc_static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX(s)];
|
168
124
|
}
|
169
125
|
|
170
126
|
int grpc_static_slice_eq(grpc_slice a, grpc_slice b) {
|
@@ -173,7 +129,7 @@ int grpc_static_slice_eq(grpc_slice a, grpc_slice b) {
|
|
173
129
|
|
174
130
|
uint32_t grpc_slice_hash(grpc_slice s) {
|
175
131
|
return s.refcount == nullptr ? grpc_slice_default_hash_impl(s)
|
176
|
-
: s.refcount->
|
132
|
+
: s.refcount->Hash(s);
|
177
133
|
}
|
178
134
|
|
179
135
|
grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice,
|
@@ -197,8 +153,9 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice,
|
|
197
153
|
}
|
198
154
|
|
199
155
|
bool grpc_slice_is_interned(const grpc_slice& slice) {
|
200
|
-
return (slice.refcount &&
|
201
|
-
|
156
|
+
return (slice.refcount &&
|
157
|
+
(slice.refcount->GetType() == grpc_slice_refcount::Type::INTERNED ||
|
158
|
+
GRPC_IS_STATIC_METADATA_STRING(slice)));
|
202
159
|
}
|
203
160
|
|
204
161
|
grpc_slice grpc_slice_intern(grpc_slice slice) {
|
@@ -208,6 +165,7 @@ grpc_slice grpc_slice_intern(grpc_slice slice) {
|
|
208
165
|
}
|
209
166
|
|
210
167
|
uint32_t hash = grpc_slice_hash(slice);
|
168
|
+
|
211
169
|
for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
|
212
170
|
static_metadata_hash_ent ent =
|
213
171
|
static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
|
@@ -217,7 +175,7 @@ grpc_slice grpc_slice_intern(grpc_slice slice) {
|
|
217
175
|
}
|
218
176
|
}
|
219
177
|
|
220
|
-
|
178
|
+
InternedSliceRefcount* s;
|
221
179
|
slice_shard* shard = &g_shards[SHARD_IDX(hash)];
|
222
180
|
|
223
181
|
gpr_mu_lock(&shard->mu);
|
@@ -226,14 +184,7 @@ grpc_slice grpc_slice_intern(grpc_slice slice) {
|
|
226
184
|
size_t idx = TABLE_IDX(hash, shard->capacity);
|
227
185
|
for (s = shard->strs[idx]; s; s = s->bucket_next) {
|
228
186
|
if (s->hash == hash && grpc_slice_eq(slice, materialize(s))) {
|
229
|
-
if (
|
230
|
-
/* If we get here, we've added a ref to something that was about to
|
231
|
-
* die - drop it immediately.
|
232
|
-
* The *only* possible path here (given the shard mutex) should be to
|
233
|
-
* drop from one ref back to zero - assert that with a CAS */
|
234
|
-
GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0));
|
235
|
-
/* and treat this as if we were never here... sshhh */
|
236
|
-
} else {
|
187
|
+
if (s->refcnt.RefIfNonZero()) {
|
237
188
|
gpr_mu_unlock(&shard->mu);
|
238
189
|
return materialize(s);
|
239
190
|
}
|
@@ -242,27 +193,20 @@ grpc_slice grpc_slice_intern(grpc_slice slice) {
|
|
242
193
|
|
243
194
|
/* not found: create a new string */
|
244
195
|
/* string data goes after the internal_string header */
|
245
|
-
s = static_cast<
|
196
|
+
s = static_cast<InternedSliceRefcount*>(
|
246
197
|
gpr_malloc(sizeof(*s) + GRPC_SLICE_LENGTH(slice)));
|
247
|
-
gpr_atm_rel_store(&s->refcnt, 1);
|
248
|
-
s->length = GRPC_SLICE_LENGTH(slice);
|
249
|
-
s->hash = hash;
|
250
|
-
s->base.vtable = &interned_slice_vtable;
|
251
|
-
s->base.sub_refcount = &s->sub;
|
252
|
-
s->sub.vtable = &interned_slice_sub_vtable;
|
253
|
-
s->sub.sub_refcount = &s->sub;
|
254
|
-
s->bucket_next = shard->strs[idx];
|
255
|
-
shard->strs[idx] = s;
|
256
|
-
memcpy(s + 1, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice));
|
257
198
|
|
199
|
+
new (s) grpc_core::InternedSliceRefcount(GRPC_SLICE_LENGTH(slice), hash,
|
200
|
+
shard->strs[idx]);
|
201
|
+
memcpy(reinterpret_cast<char*>(s + 1), GRPC_SLICE_START_PTR(slice),
|
202
|
+
GRPC_SLICE_LENGTH(slice));
|
203
|
+
shard->strs[idx] = s;
|
258
204
|
shard->count++;
|
259
|
-
|
260
205
|
if (shard->count > shard->capacity * 2) {
|
261
206
|
grow_shard(shard);
|
262
207
|
}
|
263
208
|
|
264
209
|
gpr_mu_unlock(&shard->mu);
|
265
|
-
|
266
210
|
return materialize(s);
|
267
211
|
}
|
268
212
|
|
@@ -280,7 +224,7 @@ void grpc_slice_intern_init(void) {
|
|
280
224
|
gpr_mu_init(&shard->mu);
|
281
225
|
shard->count = 0;
|
282
226
|
shard->capacity = INITIAL_SHARD_CAPACITY;
|
283
|
-
shard->strs = static_cast<
|
227
|
+
shard->strs = static_cast<InternedSliceRefcount**>(
|
284
228
|
gpr_zalloc(sizeof(*shard->strs) * shard->capacity));
|
285
229
|
}
|
286
230
|
for (size_t i = 0; i < GPR_ARRAY_SIZE(static_metadata_hash); i++) {
|
@@ -289,13 +233,13 @@ void grpc_slice_intern_init(void) {
|
|
289
233
|
}
|
290
234
|
max_static_metadata_hash_probe = 0;
|
291
235
|
for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
|
292
|
-
|
236
|
+
grpc_static_metadata_hash_values[i] =
|
293
237
|
grpc_slice_default_hash_impl(grpc_static_slice_table[i]);
|
294
238
|
for (size_t j = 0; j < GPR_ARRAY_SIZE(static_metadata_hash); j++) {
|
295
|
-
size_t slot = (
|
239
|
+
size_t slot = (grpc_static_metadata_hash_values[i] + j) %
|
296
240
|
GPR_ARRAY_SIZE(static_metadata_hash);
|
297
241
|
if (static_metadata_hash[slot].idx == GRPC_STATIC_MDSTR_COUNT) {
|
298
|
-
static_metadata_hash[slot].hash =
|
242
|
+
static_metadata_hash[slot].hash = grpc_static_metadata_hash_values[i];
|
299
243
|
static_metadata_hash[slot].idx = static_cast<uint32_t>(i);
|
300
244
|
if (j > max_static_metadata_hash_probe) {
|
301
245
|
max_static_metadata_hash_probe = static_cast<uint32_t>(j);
|
@@ -315,8 +259,7 @@ void grpc_slice_intern_shutdown(void) {
|
|
315
259
|
gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked",
|
316
260
|
shard->count);
|
317
261
|
for (size_t j = 0; j < shard->capacity; j++) {
|
318
|
-
for (
|
319
|
-
s = s->bucket_next) {
|
262
|
+
for (InternedSliceRefcount* s = shard->strs[j]; s; s = s->bucket_next) {
|
320
263
|
char* text =
|
321
264
|
grpc_dump_slice(materialize(s), GPR_DUMP_HEX | GPR_DUMP_ASCII);
|
322
265
|
gpr_log(GPR_DEBUG, "LEAKED: %s", text);
|
@@ -23,17 +23,215 @@
|
|
23
23
|
|
24
24
|
#include <grpc/slice.h>
|
25
25
|
#include <grpc/slice_buffer.h>
|
26
|
+
#include <string.h>
|
27
|
+
|
28
|
+
#include "src/core/lib/gpr/murmur_hash.h"
|
29
|
+
#include "src/core/lib/gprpp/ref_counted.h"
|
30
|
+
#include "src/core/lib/transport/static_metadata.h"
|
31
|
+
|
32
|
+
// Interned slices have specific fast-path operations for hashing. To inline
|
33
|
+
// these operations, we need to forward declare them here.
|
34
|
+
extern uint32_t grpc_static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT];
|
35
|
+
extern uint32_t g_hash_seed;
|
36
|
+
|
37
|
+
// grpc_slice_refcount : A reference count for grpc_slice.
|
38
|
+
//
|
39
|
+
// Non-inlined grpc_slice objects are refcounted. Historically this was
|
40
|
+
// implemented via grpc_slice_refcount, a C-style polymorphic class using a
|
41
|
+
// manually managed vtable of operations. Subclasses would define their own
|
42
|
+
// vtable; the 'virtual' methods (ref, unref, equals and hash) would simply call
|
43
|
+
// the function pointers in the vtable as necessary.
|
44
|
+
//
|
45
|
+
// Unfortunately, this leads to some inefficiencies in the generated code that
|
46
|
+
// can be improved upon. For example, equality checking for interned slices is a
|
47
|
+
// simple equality check on the refcount pointer. With the vtable approach, this
|
48
|
+
// would translate to roughly the following (high-level) instructions:
|
49
|
+
//
|
50
|
+
// grpc_slice_equals(slice1, slice2):
|
51
|
+
// load vtable->eq -> eq_func
|
52
|
+
// call eq_func(slice1, slice2)
|
53
|
+
//
|
54
|
+
// interned_slice_equals(slice1, slice2)
|
55
|
+
// load slice1.ref -> r1
|
56
|
+
// load slice2.ref -> r2
|
57
|
+
// cmp r1, r2 -> retval
|
58
|
+
// ret retval
|
59
|
+
//
|
60
|
+
// This leads to a function call for a function defined in another translation
|
61
|
+
// unit, which imposes memory barriers, which reduces the compiler's ability to
|
62
|
+
// optimize (in addition to the added overhead of call/ret). Additionally, it
|
63
|
+
// may be harder to reason about branch prediction when we're jumping to
|
64
|
+
// essentially arbitrarily provided function pointers.
|
65
|
+
//
|
66
|
+
// In addition, it is arguable that while virtualization was helpful for
|
67
|
+
// Equals()/Hash() methods, that it was fundamentally unnecessary for
|
68
|
+
// Ref()/Unref().
|
69
|
+
//
|
70
|
+
// Instead, grpc_slice_refcount provides the same functionality as the C-style
|
71
|
+
// virtual class, but in a de-virtualized manner - Eq(), Hash(), Ref() and
|
72
|
+
// Unref() are provided within this header file. Fastpaths for Eq()/Hash()
|
73
|
+
// (interned and static metadata slices), as well as the Ref() operation, can
|
74
|
+
// all be inlined without any memory barriers.
|
75
|
+
//
|
76
|
+
// It does this by:
|
77
|
+
// 1. Using grpc_core::RefCount<> (header-only) for Ref/Unref. Two special cases
|
78
|
+
// need support: No-op ref/unref (eg. static metadata slices) and stream
|
79
|
+
// slice references (where all the slices share the streamref). This is in
|
80
|
+
// addition to the normal case of '1 slice, 1 ref'.
|
81
|
+
// To support these cases, we explicitly track a nullable pointer to the
|
82
|
+
// underlying RefCount<>. No-op ref/unref is used by checking the pointer for
|
83
|
+
// null, and doing nothing if it is. Both stream slice refs and 'normal'
|
84
|
+
// slices use the same path for Ref/Unref (by targeting the non-null
|
85
|
+
// pointer).
|
86
|
+
//
|
87
|
+
// 2. introducing the notion of grpc_slice_refcount::Type. This describes if a
|
88
|
+
// slice ref is used by a static metadata slice, an interned slice, or other
|
89
|
+
// slices. We switch on the slice ref type in order to provide fastpaths for
|
90
|
+
// Equals() and Hash().
|
91
|
+
//
|
92
|
+
// In total, this saves us roughly 1-2% latency for unary calls, with smaller
|
93
|
+
// calls benefitting. The effect is present, but not as useful, for larger calls
|
94
|
+
// where the cost of sending the data dominates.
|
95
|
+
struct grpc_slice_refcount {
|
96
|
+
public:
|
97
|
+
enum class Type {
|
98
|
+
STATIC, // Refcount for a static metadata slice.
|
99
|
+
INTERNED, // Refcount for an interned slice.
|
100
|
+
REGULAR // Refcount for non-static-metadata, non-interned slices.
|
101
|
+
};
|
102
|
+
typedef void (*DestroyerFn)(void*);
|
103
|
+
|
104
|
+
grpc_slice_refcount() = default;
|
105
|
+
|
106
|
+
explicit grpc_slice_refcount(grpc_slice_refcount* sub) : sub_refcount_(sub) {}
|
107
|
+
// Regular constructor for grpc_slice_refcount.
|
108
|
+
//
|
109
|
+
// Parameters:
|
110
|
+
// 1. grpc_slice_refcount::Type type
|
111
|
+
// Whether we are the refcount for a static
|
112
|
+
// metadata slice, an interned slice, or any other kind of slice.
|
113
|
+
//
|
114
|
+
// 2. RefCount* ref
|
115
|
+
// The pointer to the actual underlying grpc_core::RefCount. Rather than
|
116
|
+
// performing struct offset computations as in the original implementation to
|
117
|
+
// get to the refcount, which requires a virtual method, we devirtualize by
|
118
|
+
// using a nullable pointer to allow a single pair of Ref/Unref methods.
|
119
|
+
//
|
120
|
+
// 3. DestroyerFn destroyer_fn
|
121
|
+
// Called when the refcount goes to 0, with destroyer_arg as parameter.
|
122
|
+
//
|
123
|
+
// 4. void* destroyer_arg
|
124
|
+
// Argument for the virtualized destructor.
|
125
|
+
//
|
126
|
+
// 5. grpc_slice_refcount* sub
|
127
|
+
// Argument used for interned slices.
|
128
|
+
grpc_slice_refcount(grpc_slice_refcount::Type type, grpc_core::RefCount* ref,
|
129
|
+
DestroyerFn destroyer_fn, void* destroyer_arg,
|
130
|
+
grpc_slice_refcount* sub)
|
131
|
+
: ref_(ref),
|
132
|
+
ref_type_(type),
|
133
|
+
sub_refcount_(sub),
|
134
|
+
dest_fn_(destroyer_fn),
|
135
|
+
destroy_fn_arg_(destroyer_arg) {}
|
136
|
+
// Initializer for static refcounts.
|
137
|
+
grpc_slice_refcount(grpc_slice_refcount* sub, Type type)
|
138
|
+
: ref_type_(type), sub_refcount_(sub) {}
|
139
|
+
|
140
|
+
Type GetType() const { return ref_type_; }
|
141
|
+
|
142
|
+
int Eq(const grpc_slice& a, const grpc_slice& b);
|
143
|
+
|
144
|
+
uint32_t Hash(const grpc_slice& slice);
|
145
|
+
void Ref() {
|
146
|
+
if (ref_ == nullptr) return;
|
147
|
+
ref_->RefNonZero();
|
148
|
+
}
|
149
|
+
void Unref() {
|
150
|
+
if (ref_ == nullptr) return;
|
151
|
+
if (ref_->Unref()) {
|
152
|
+
dest_fn_(destroy_fn_arg_);
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
grpc_slice_refcount* sub_refcount() const { return sub_refcount_; }
|
157
|
+
|
158
|
+
private:
|
159
|
+
grpc_core::RefCount* ref_ = nullptr;
|
160
|
+
const Type ref_type_ = Type::REGULAR;
|
161
|
+
grpc_slice_refcount* sub_refcount_ = this;
|
162
|
+
DestroyerFn dest_fn_ = nullptr;
|
163
|
+
void* destroy_fn_arg_ = nullptr;
|
164
|
+
};
|
165
|
+
|
166
|
+
namespace grpc_core {
|
167
|
+
|
168
|
+
struct InternedSliceRefcount {
|
169
|
+
static void Destroy(void* arg) {
|
170
|
+
auto* rc = static_cast<InternedSliceRefcount*>(arg);
|
171
|
+
rc->~InternedSliceRefcount();
|
172
|
+
gpr_free(rc);
|
173
|
+
}
|
174
|
+
|
175
|
+
InternedSliceRefcount(size_t length, uint32_t hash,
|
176
|
+
InternedSliceRefcount* bucket_next)
|
177
|
+
: base(grpc_slice_refcount::Type::INTERNED, &refcnt, Destroy, this, &sub),
|
178
|
+
sub(grpc_slice_refcount::Type::REGULAR, &refcnt, Destroy, this, &sub),
|
179
|
+
length(length),
|
180
|
+
hash(hash),
|
181
|
+
bucket_next(bucket_next) {}
|
182
|
+
|
183
|
+
~InternedSliceRefcount();
|
184
|
+
|
185
|
+
grpc_slice_refcount base;
|
186
|
+
grpc_slice_refcount sub;
|
187
|
+
const size_t length;
|
188
|
+
RefCount refcnt;
|
189
|
+
const uint32_t hash;
|
190
|
+
InternedSliceRefcount* bucket_next;
|
191
|
+
};
|
192
|
+
|
193
|
+
} // namespace grpc_core
|
194
|
+
|
195
|
+
inline int grpc_slice_refcount::Eq(const grpc_slice& a, const grpc_slice& b) {
|
196
|
+
switch (ref_type_) {
|
197
|
+
case Type::STATIC:
|
198
|
+
return GRPC_STATIC_METADATA_INDEX(a) == GRPC_STATIC_METADATA_INDEX(b);
|
199
|
+
case Type::INTERNED:
|
200
|
+
return a.refcount == b.refcount;
|
201
|
+
case Type::REGULAR:
|
202
|
+
break;
|
203
|
+
}
|
204
|
+
if (GRPC_SLICE_LENGTH(a) != GRPC_SLICE_LENGTH(b)) return false;
|
205
|
+
if (GRPC_SLICE_LENGTH(a) == 0) return true;
|
206
|
+
return 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
|
207
|
+
GRPC_SLICE_LENGTH(a));
|
208
|
+
}
|
209
|
+
|
210
|
+
inline uint32_t grpc_slice_refcount::Hash(const grpc_slice& slice) {
|
211
|
+
switch (ref_type_) {
|
212
|
+
case Type::STATIC:
|
213
|
+
return ::grpc_static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX(
|
214
|
+
slice)];
|
215
|
+
case Type::INTERNED:
|
216
|
+
return reinterpret_cast<grpc_core::InternedSliceRefcount*>(slice.refcount)
|
217
|
+
->hash;
|
218
|
+
case Type::REGULAR:
|
219
|
+
break;
|
220
|
+
}
|
221
|
+
return gpr_murmur_hash3(GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice),
|
222
|
+
g_hash_seed);
|
223
|
+
}
|
26
224
|
|
27
225
|
inline const grpc_slice& grpc_slice_ref_internal(const grpc_slice& slice) {
|
28
226
|
if (slice.refcount) {
|
29
|
-
slice.refcount->
|
227
|
+
slice.refcount->Ref();
|
30
228
|
}
|
31
229
|
return slice;
|
32
230
|
}
|
33
231
|
|
34
232
|
inline void grpc_slice_unref_internal(const grpc_slice& slice) {
|
35
233
|
if (slice.refcount) {
|
36
|
-
slice.refcount->
|
234
|
+
slice.refcount->Unref();
|
37
235
|
}
|
38
236
|
}
|
39
237
|
|