grpc 1.21.0 → 1.22.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.

Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +422 -62
  3. data/include/grpc/grpc_security.h +61 -5
  4. data/include/grpc/grpc_security_constants.h +1 -1
  5. data/include/grpc/impl/codegen/gpr_types.h +1 -1
  6. data/include/grpc/slice.h +2 -2
  7. data/src/core/ext/filters/client_channel/backup_poller.cc +2 -3
  8. data/src/core/ext/filters/client_channel/backup_poller.h +5 -2
  9. data/src/core/ext/filters/client_channel/client_channel.cc +260 -122
  10. data/src/core/ext/filters/client_channel/client_channel.h +0 -8
  11. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +3 -84
  12. data/src/core/ext/filters/client_channel/client_channel_channelz.h +2 -28
  13. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +2 -8
  14. data/src/core/ext/filters/client_channel/health/health_check_client.cc +5 -4
  15. data/src/core/ext/filters/client_channel/lb_policy.cc +16 -2
  16. data/src/core/ext/filters/client_channel/lb_policy.h +92 -98
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +63 -87
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +6 -2
  19. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +35 -87
  20. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +18 -74
  21. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +167 -217
  22. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +216 -190
  23. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +6 -2
  24. data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -1
  25. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +1 -1
  26. data/src/core/ext/filters/client_channel/lb_policy_registry.h +1 -1
  27. data/src/core/ext/filters/client_channel/resolver.h +1 -1
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +6 -3
  29. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +0 -1
  30. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -0
  31. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +8 -8
  32. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +7 -7
  33. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +28 -64
  34. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +4 -12
  35. data/src/core/ext/filters/client_channel/server_address.cc +4 -6
  36. data/src/core/ext/filters/client_channel/server_address.h +1 -3
  37. data/src/core/ext/filters/client_channel/service_config.cc +20 -22
  38. data/src/core/ext/filters/client_channel/service_config.h +26 -28
  39. data/src/core/ext/filters/client_channel/subchannel.cc +261 -160
  40. data/src/core/ext/filters/client_channel/subchannel.h +97 -23
  41. data/src/core/ext/filters/client_channel/subchannel_interface.h +113 -0
  42. data/src/core/ext/filters/message_size/message_size_filter.cc +12 -12
  43. data/src/core/ext/filters/message_size/message_size_filter.h +2 -2
  44. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +50 -2
  45. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +2 -2
  46. data/src/core/ext/transport/chttp2/transport/frame_data.cc +31 -36
  47. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +3 -2
  48. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +71 -52
  49. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +18 -3
  50. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +5 -12
  51. data/src/core/ext/transport/chttp2/transport/hpack_table.h +10 -1
  52. data/src/core/ext/transport/chttp2/transport/internal.h +3 -3
  53. data/src/core/ext/transport/chttp2/transport/parsing.cc +39 -57
  54. data/src/core/lib/channel/channelz.cc +136 -19
  55. data/src/core/lib/channel/channelz.h +36 -40
  56. data/src/core/lib/channel/channelz_registry.cc +74 -106
  57. data/src/core/lib/channel/channelz_registry.h +10 -28
  58. data/src/core/lib/channel/context.h +1 -1
  59. data/src/core/lib/channel/handshaker.cc +6 -0
  60. data/src/core/lib/compression/compression.cc +13 -8
  61. data/src/core/lib/compression/compression_internal.cc +14 -10
  62. data/src/core/lib/compression/compression_internal.h +1 -1
  63. data/src/core/lib/compression/stream_compression.cc +3 -2
  64. data/src/core/lib/compression/stream_compression.h +2 -2
  65. data/src/core/lib/compression/stream_compression_gzip.cc +9 -9
  66. data/src/core/lib/gpr/env.h +1 -1
  67. data/src/core/lib/gpr/string.cc +8 -1
  68. data/src/core/lib/gpr/string.h +6 -1
  69. data/src/core/lib/gprpp/fork.cc +1 -1
  70. data/src/core/lib/gprpp/fork.h +5 -1
  71. data/src/core/lib/gprpp/global_config.h +9 -0
  72. data/src/core/lib/gprpp/global_config_custom.h +1 -1
  73. data/src/core/lib/gprpp/inlined_vector.h +8 -0
  74. data/src/core/lib/gprpp/map.h +38 -21
  75. data/src/core/lib/gprpp/memory.h +2 -2
  76. data/src/core/lib/gprpp/orphanable.h +1 -1
  77. data/src/core/lib/gprpp/ref_counted.h +9 -4
  78. data/src/core/lib/http/httpcli.cc +3 -3
  79. data/src/core/lib/iomgr/buffer_list.h +1 -1
  80. data/src/core/lib/iomgr/call_combiner.cc +1 -1
  81. data/src/core/lib/iomgr/call_combiner.h +1 -1
  82. data/src/core/lib/iomgr/cfstream_handle.cc +3 -2
  83. data/src/core/lib/iomgr/cfstream_handle.h +4 -0
  84. data/src/core/lib/iomgr/error.cc +3 -3
  85. data/src/core/lib/iomgr/error.h +9 -3
  86. data/src/core/lib/iomgr/error_internal.h +1 -1
  87. data/src/core/lib/iomgr/ev_epoll1_linux.cc +1 -1
  88. data/src/core/lib/iomgr/ev_posix.cc +3 -3
  89. data/src/core/lib/iomgr/ev_posix.h +3 -2
  90. data/src/core/lib/iomgr/ev_windows.cc +2 -2
  91. data/src/core/lib/iomgr/iomgr.cc +4 -4
  92. data/src/core/lib/iomgr/lockfree_event.cc +1 -1
  93. data/src/core/lib/iomgr/port.h +5 -1
  94. data/src/core/lib/iomgr/tcp_posix.cc +1 -3
  95. data/src/core/lib/iomgr/tcp_server.cc +5 -0
  96. data/src/core/lib/iomgr/tcp_server.h +24 -0
  97. data/src/core/lib/iomgr/tcp_server_custom.cc +11 -9
  98. data/src/core/lib/iomgr/tcp_server_posix.cc +72 -11
  99. data/src/core/lib/iomgr/tcp_server_utils_posix.h +3 -0
  100. data/src/core/lib/iomgr/tcp_server_windows.cc +11 -9
  101. data/src/core/lib/iomgr/tcp_uv.cc +5 -6
  102. data/src/core/lib/iomgr/timer.h +2 -1
  103. data/src/core/lib/iomgr/udp_server.cc +2 -2
  104. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +1 -1
  105. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +20 -2
  106. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +2 -2
  107. data/src/core/lib/security/security_connector/security_connector.h +1 -1
  108. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +1 -1
  109. data/src/core/lib/security/transport/auth_filters.h +3 -0
  110. data/src/core/lib/security/transport/client_auth_filter.cc +13 -0
  111. data/src/core/lib/security/transport/security_handshaker.cc +7 -7
  112. data/src/core/lib/slice/b64.h +2 -2
  113. data/src/core/lib/slice/slice.cc +82 -10
  114. data/src/core/lib/slice/slice_buffer.cc +49 -21
  115. data/src/core/lib/slice/slice_hash_table.h +2 -2
  116. data/src/core/lib/slice/slice_intern.cc +15 -16
  117. data/src/core/lib/slice/slice_internal.h +52 -0
  118. data/src/core/lib/slice/slice_string_helpers.cc +10 -1
  119. data/src/core/lib/slice/slice_string_helpers.h +3 -1
  120. data/src/core/lib/slice/slice_utils.h +50 -0
  121. data/src/core/lib/slice/slice_weak_hash_table.h +2 -2
  122. data/src/core/lib/surface/call.cc +14 -8
  123. data/src/core/lib/surface/channel.cc +89 -97
  124. data/src/core/lib/surface/channel.h +60 -6
  125. data/src/core/lib/surface/completion_queue.cc +49 -36
  126. data/src/core/lib/surface/completion_queue.h +2 -1
  127. data/src/core/lib/surface/server.cc +8 -8
  128. data/src/core/lib/surface/validate_metadata.cc +14 -8
  129. data/src/core/lib/surface/validate_metadata.h +13 -2
  130. data/src/core/lib/surface/version.cc +1 -1
  131. data/src/core/lib/transport/metadata.cc +56 -26
  132. data/src/core/lib/transport/metadata.h +91 -75
  133. data/src/core/lib/transport/static_metadata.cc +262 -176
  134. data/src/core/lib/transport/static_metadata.h +272 -180
  135. data/src/core/lib/transport/transport.cc +1 -1
  136. data/src/core/lib/transport/transport.h +8 -2
  137. data/src/core/tsi/alts/handshaker/alts_shared_resource.h +1 -1
  138. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  139. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +5 -2
  140. data/src/ruby/lib/grpc/version.rb +1 -1
  141. metadata +33 -31
@@ -32,35 +32,45 @@
32
32
  /* grow a buffer; requires GRPC_SLICE_BUFFER_INLINE_ELEMENTS > 1 */
33
33
  #define GROW(x) (3 * (x) / 2)
34
34
 
35
+ /* Typically, we do not actually need to embiggen (by calling
36
+ * memmove/malloc/realloc) - only if we were up against the full capacity of the
37
+ * slice buffer. If do_embiggen is inlined, the compiler clobbers multiple
38
+ * registers pointlessly in the common case. */
39
+ static void GPR_ATTRIBUTE_NOINLINE do_embiggen(grpc_slice_buffer* sb,
40
+ const size_t slice_count,
41
+ const size_t slice_offset) {
42
+ if (slice_offset != 0) {
43
+ /* Make room by moving elements if there's still space unused */
44
+ memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
45
+ sb->slices = sb->base_slices;
46
+ } else {
47
+ /* Allocate more memory if no more space is available */
48
+ const size_t new_capacity = GROW(sb->capacity);
49
+ sb->capacity = new_capacity;
50
+ if (sb->base_slices == sb->inlined) {
51
+ sb->base_slices = static_cast<grpc_slice*>(
52
+ gpr_malloc(new_capacity * sizeof(grpc_slice)));
53
+ memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
54
+ } else {
55
+ sb->base_slices = static_cast<grpc_slice*>(
56
+ gpr_realloc(sb->base_slices, new_capacity * sizeof(grpc_slice)));
57
+ }
58
+
59
+ sb->slices = sb->base_slices + slice_offset;
60
+ }
61
+ }
62
+
35
63
  static void maybe_embiggen(grpc_slice_buffer* sb) {
36
64
  if (sb->count == 0) {
37
65
  sb->slices = sb->base_slices;
66
+ return;
38
67
  }
39
68
 
40
69
  /* How far away from sb->base_slices is sb->slices pointer */
41
70
  size_t slice_offset = static_cast<size_t>(sb->slices - sb->base_slices);
42
71
  size_t slice_count = sb->count + slice_offset;
43
-
44
- if (slice_count == sb->capacity) {
45
- if (sb->base_slices != sb->slices) {
46
- /* Make room by moving elements if there's still space unused */
47
- memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
48
- sb->slices = sb->base_slices;
49
- } else {
50
- /* Allocate more memory if no more space is available */
51
- sb->capacity = GROW(sb->capacity);
52
- GPR_ASSERT(sb->capacity > slice_count);
53
- if (sb->base_slices == sb->inlined) {
54
- sb->base_slices = static_cast<grpc_slice*>(
55
- gpr_malloc(sb->capacity * sizeof(grpc_slice)));
56
- memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
57
- } else {
58
- sb->base_slices = static_cast<grpc_slice*>(
59
- gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice)));
60
- }
61
-
62
- sb->slices = sb->base_slices + slice_offset;
63
- }
72
+ if (GPR_UNLIKELY(slice_count == sb->capacity)) {
73
+ do_embiggen(sb, slice_count, slice_offset);
64
74
  }
65
75
  }
66
76
 
@@ -375,6 +385,24 @@ grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer* sb) {
375
385
  return slice;
376
386
  }
377
387
 
388
+ void grpc_slice_buffer_remove_first(grpc_slice_buffer* sb) {
389
+ GPR_DEBUG_ASSERT(sb->count > 0);
390
+ sb->length -= GRPC_SLICE_LENGTH(sb->slices[0]);
391
+ grpc_slice_unref_internal(sb->slices[0]);
392
+ sb->slices++;
393
+ if (--sb->count == 0) {
394
+ sb->slices = sb->base_slices;
395
+ }
396
+ }
397
+
398
+ void grpc_slice_buffer_sub_first(grpc_slice_buffer* sb, size_t begin,
399
+ size_t end) {
400
+ // TODO(soheil): Introduce a ptr version for sub.
401
+ sb->length -= GRPC_SLICE_LENGTH(sb->slices[0]);
402
+ sb->slices[0] = grpc_slice_sub_no_ref(sb->slices[0], begin, end);
403
+ sb->length += end - begin;
404
+ }
405
+
378
406
  void grpc_slice_buffer_undo_take_first(grpc_slice_buffer* sb,
379
407
  grpc_slice slice) {
380
408
  sb->slices--;
@@ -138,7 +138,7 @@ SliceHashTable<T>::~SliceHashTable() {
138
138
 
139
139
  template <typename T>
140
140
  void SliceHashTable<T>::Add(const grpc_slice& key, T& value) {
141
- const size_t hash = grpc_slice_hash(key);
141
+ const size_t hash = grpc_slice_hash_internal(key);
142
142
  for (size_t offset = 0; offset < size_; ++offset) {
143
143
  const size_t idx = (hash + offset) % size_;
144
144
  if (!entries_[idx].is_set) {
@@ -156,7 +156,7 @@ void SliceHashTable<T>::Add(const grpc_slice& key, T& value) {
156
156
 
157
157
  template <typename T>
158
158
  const T* SliceHashTable<T>::Get(const grpc_slice& key) const {
159
- const size_t hash = grpc_slice_hash(key);
159
+ const size_t hash = grpc_slice_hash_internal(key);
160
160
  // We cap the number of probes at the max number recorded when
161
161
  // populating the table.
162
162
  for (size_t offset = 0; offset <= max_num_probes_; ++offset) {
@@ -19,6 +19,7 @@
19
19
  #include <grpc/support/port_platform.h>
20
20
 
21
21
  #include "src/core/lib/slice/slice_internal.h"
22
+ #include "src/core/lib/slice/slice_utils.h"
22
23
 
23
24
  #include <inttypes.h>
24
25
  #include <string.h>
@@ -127,10 +128,7 @@ int grpc_static_slice_eq(grpc_slice a, grpc_slice b) {
127
128
  return GRPC_STATIC_METADATA_INDEX(a) == GRPC_STATIC_METADATA_INDEX(b);
128
129
  }
129
130
 
130
- uint32_t grpc_slice_hash(grpc_slice s) {
131
- return s.refcount == nullptr ? grpc_slice_default_hash_impl(s)
132
- : s.refcount->Hash(s);
133
- }
131
+ uint32_t grpc_slice_hash(grpc_slice s) { return grpc_slice_hash_internal(s); }
134
132
 
135
133
  grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice,
136
134
  bool* returned_slice_is_different) {
@@ -138,12 +136,13 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice,
138
136
  return slice;
139
137
  }
140
138
 
141
- uint32_t hash = grpc_slice_hash(slice);
139
+ uint32_t hash = grpc_slice_hash_internal(slice);
142
140
  for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
143
141
  static_metadata_hash_ent ent =
144
142
  static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
145
143
  if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
146
- grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) {
144
+ grpc_slice_eq_static_interned(slice,
145
+ grpc_static_slice_table[ent.idx])) {
147
146
  *returned_slice_is_different = true;
148
147
  return grpc_static_slice_table[ent.idx];
149
148
  }
@@ -152,25 +151,20 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice,
152
151
  return slice;
153
152
  }
154
153
 
155
- bool grpc_slice_is_interned(const grpc_slice& slice) {
156
- return (slice.refcount &&
157
- (slice.refcount->GetType() == grpc_slice_refcount::Type::INTERNED ||
158
- GRPC_IS_STATIC_METADATA_STRING(slice)));
159
- }
160
-
161
154
  grpc_slice grpc_slice_intern(grpc_slice slice) {
162
155
  GPR_TIMER_SCOPE("grpc_slice_intern", 0);
163
156
  if (GRPC_IS_STATIC_METADATA_STRING(slice)) {
164
157
  return slice;
165
158
  }
166
159
 
167
- uint32_t hash = grpc_slice_hash(slice);
160
+ uint32_t hash = grpc_slice_hash_internal(slice);
168
161
 
169
162
  for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
170
163
  static_metadata_hash_ent ent =
171
164
  static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
172
165
  if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
173
- grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) {
166
+ grpc_slice_eq_static_interned(slice,
167
+ grpc_static_slice_table[ent.idx])) {
174
168
  return grpc_static_slice_table[ent.idx];
175
169
  }
176
170
  }
@@ -183,7 +177,8 @@ grpc_slice grpc_slice_intern(grpc_slice slice) {
183
177
  /* search for an existing string */
184
178
  size_t idx = TABLE_IDX(hash, shard->capacity);
185
179
  for (s = shard->strs[idx]; s; s = s->bucket_next) {
186
- if (s->hash == hash && grpc_slice_eq(slice, materialize(s))) {
180
+ if (s->hash == hash &&
181
+ grpc_slice_eq_static_interned(slice, materialize(s))) {
187
182
  if (s->refcnt.RefIfNonZero()) {
188
183
  gpr_mu_unlock(&shard->mu);
189
184
  return materialize(s);
@@ -234,7 +229,7 @@ void grpc_slice_intern_init(void) {
234
229
  max_static_metadata_hash_probe = 0;
235
230
  for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
236
231
  grpc_static_metadata_hash_values[i] =
237
- grpc_slice_default_hash_impl(grpc_static_slice_table[i]);
232
+ grpc_slice_default_hash_internal(grpc_static_slice_table[i]);
238
233
  for (size_t j = 0; j < GPR_ARRAY_SIZE(static_metadata_hash); j++) {
239
234
  size_t slot = (grpc_static_metadata_hash_values[i] + j) %
240
235
  GPR_ARRAY_SIZE(static_metadata_hash);
@@ -248,6 +243,10 @@ void grpc_slice_intern_init(void) {
248
243
  }
249
244
  }
250
245
  }
246
+ // Handle KV hash for all static mdelems.
247
+ for (size_t i = 0; i < GRPC_STATIC_MDELEM_COUNT; ++i) {
248
+ grpc_static_mdelem_table[i].HashInit();
249
+ }
251
250
  }
252
251
 
253
252
  void grpc_slice_intern_shutdown(void) {
@@ -21,11 +21,14 @@
21
21
 
22
22
  #include <grpc/support/port_platform.h>
23
23
 
24
+ #include <grpc/support/log.h>
25
+
24
26
  #include <grpc/slice.h>
25
27
  #include <grpc/slice_buffer.h>
26
28
  #include <string.h>
27
29
 
28
30
  #include "src/core/lib/gpr/murmur_hash.h"
31
+ #include "src/core/lib/gprpp/memory.h"
29
32
  #include "src/core/lib/gprpp/ref_counted.h"
30
33
  #include "src/core/lib/transport/static_metadata.h"
31
34
 
@@ -97,12 +100,15 @@ struct grpc_slice_refcount {
97
100
  enum class Type {
98
101
  STATIC, // Refcount for a static metadata slice.
99
102
  INTERNED, // Refcount for an interned slice.
103
+ NOP, // No-Op
100
104
  REGULAR // Refcount for non-static-metadata, non-interned slices.
101
105
  };
102
106
  typedef void (*DestroyerFn)(void*);
103
107
 
104
108
  grpc_slice_refcount() = default;
105
109
 
110
+ explicit grpc_slice_refcount(Type t) : ref_type_(t) {}
111
+
106
112
  explicit grpc_slice_refcount(grpc_slice_refcount* sub) : sub_refcount_(sub) {}
107
113
  // Regular constructor for grpc_slice_refcount.
108
114
  //
@@ -198,6 +204,7 @@ inline int grpc_slice_refcount::Eq(const grpc_slice& a, const grpc_slice& b) {
198
204
  return GRPC_STATIC_METADATA_INDEX(a) == GRPC_STATIC_METADATA_INDEX(b);
199
205
  case Type::INTERNED:
200
206
  return a.refcount == b.refcount;
207
+ case Type::NOP:
201
208
  case Type::REGULAR:
202
209
  break;
203
210
  }
@@ -215,6 +222,7 @@ inline uint32_t grpc_slice_refcount::Hash(const grpc_slice& slice) {
215
222
  case Type::INTERNED:
216
223
  return reinterpret_cast<grpc_core::InternedSliceRefcount*>(slice.refcount)
217
224
  ->hash;
225
+ case Type::NOP:
218
226
  case Type::REGULAR:
219
227
  break;
220
228
  }
@@ -240,8 +248,33 @@ void grpc_slice_buffer_partial_unref_internal(grpc_slice_buffer* sb,
240
248
  size_t idx);
241
249
  void grpc_slice_buffer_destroy_internal(grpc_slice_buffer* sb);
242
250
 
251
+ // Returns a pointer to the first slice in the slice buffer without giving
252
+ // ownership to or a reference count on that slice.
253
+ inline grpc_slice* grpc_slice_buffer_peek_first(grpc_slice_buffer* sb) {
254
+ GPR_DEBUG_ASSERT(sb->count > 0);
255
+ return &sb->slices[0];
256
+ }
257
+
258
+ // Removes the first slice from the slice buffer.
259
+ void grpc_slice_buffer_remove_first(grpc_slice_buffer* sb);
260
+
261
+ // Calls grpc_slice_sub with the given parameters on the first slice.
262
+ void grpc_slice_buffer_sub_first(grpc_slice_buffer* sb, size_t begin,
263
+ size_t end);
264
+
243
265
  /* Check if a slice is interned */
244
266
  bool grpc_slice_is_interned(const grpc_slice& slice);
267
+ inline bool grpc_slice_is_interned(const grpc_slice& slice) {
268
+ return (slice.refcount &&
269
+ (slice.refcount->GetType() == grpc_slice_refcount::Type::INTERNED ||
270
+ slice.refcount->GetType() == grpc_slice_refcount::Type::STATIC));
271
+ }
272
+
273
+ inline bool grpc_slice_static_interned_equal(const grpc_slice& a,
274
+ const grpc_slice& b) {
275
+ GPR_DEBUG_ASSERT(grpc_slice_is_interned(a) && grpc_slice_is_interned(b));
276
+ return a.refcount == b.refcount;
277
+ }
245
278
 
246
279
  void grpc_slice_intern_init(void);
247
280
  void grpc_slice_intern_shutdown(void);
@@ -255,6 +288,25 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice,
255
288
  uint32_t grpc_static_slice_hash(grpc_slice s);
256
289
  int grpc_static_slice_eq(grpc_slice a, grpc_slice b);
257
290
 
291
+ inline uint32_t grpc_slice_hash_refcounted(const grpc_slice& s) {
292
+ GPR_DEBUG_ASSERT(s.refcount != nullptr);
293
+ return s.refcount->Hash(s);
294
+ }
295
+
296
+ inline uint32_t grpc_slice_default_hash_internal(const grpc_slice& s) {
297
+ return gpr_murmur_hash3(GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s),
298
+ g_hash_seed);
299
+ }
300
+
301
+ inline uint32_t grpc_slice_hash_internal(const grpc_slice& s) {
302
+ return s.refcount == nullptr ? grpc_slice_default_hash_internal(s)
303
+ : grpc_slice_hash_refcounted(s);
304
+ }
305
+
306
+ grpc_slice grpc_slice_from_moved_buffer(grpc_core::UniquePtr<char> p,
307
+ size_t len);
308
+ grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr<char> p);
309
+
258
310
  // Returns the memory used by this slice, not counting the slice structure
259
311
  // itself. This means that inlined and slices from static strings will return
260
312
  // 0. All other slices will return the size of the allocated chars.
@@ -25,13 +25,22 @@
25
25
  #include <grpc/support/log.h>
26
26
 
27
27
  #include "src/core/lib/gpr/string.h"
28
+ #include "src/core/lib/gprpp/memory.h"
28
29
  #include "src/core/lib/slice/slice_internal.h"
29
30
 
30
- char* grpc_dump_slice(grpc_slice s, uint32_t flags) {
31
+ char* grpc_dump_slice(const grpc_slice& s, uint32_t flags) {
31
32
  return gpr_dump(reinterpret_cast<const char*> GRPC_SLICE_START_PTR(s),
32
33
  GRPC_SLICE_LENGTH(s), flags);
33
34
  }
34
35
 
36
+ grpc_slice grpc_dump_slice_to_slice(const grpc_slice& s, uint32_t flags) {
37
+ size_t len;
38
+ grpc_core::UniquePtr<char> ptr(
39
+ gpr_dump_return_len(reinterpret_cast<const char*> GRPC_SLICE_START_PTR(s),
40
+ GRPC_SLICE_LENGTH(s), flags, &len));
41
+ return grpc_slice_from_moved_buffer(std::move(ptr), len);
42
+ }
43
+
35
44
  /** Finds the initial (\a begin) and final (\a end) offsets of the next
36
45
  * substring from \a str + \a read_offset until the next \a sep or the end of \a
37
46
  * str.
@@ -30,7 +30,9 @@
30
30
  #include "src/core/lib/gpr/string.h"
31
31
 
32
32
  /* Calls gpr_dump on a slice. */
33
- char* grpc_dump_slice(grpc_slice slice, uint32_t flags);
33
+ char* grpc_dump_slice(const grpc_slice& slice, uint32_t flags);
34
+ /* Calls gpr_dump on a slice and returns the result as a slice. */
35
+ grpc_slice grpc_dump_slice_to_slice(const grpc_slice& slice, uint32_t flags);
34
36
 
35
37
  /** Split \a str by the separator \a sep. Results are stored in \a dst, which
36
38
  * should be a properly initialized instance. */
@@ -0,0 +1,50 @@
1
+ /*
2
+ *
3
+ * Copyright 2019 gRPC authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+
19
+ #ifndef GRPC_CORE_LIB_SLICE_SLICE_UTILS_H
20
+ #define GRPC_CORE_LIB_SLICE_SLICE_UTILS_H
21
+
22
+ #include <grpc/support/port_platform.h>
23
+
24
+ #include <grpc/slice.h>
25
+
26
+ // When we compare two slices, and we know the latter is not inlined, we can
27
+ // short circuit our comparison operator. We specifically use differs()
28
+ // semantics instead of equals() semantics due to more favourable code
29
+ // generation when using differs(). Specifically, we may use the output of
30
+ // grpc_slice_differs_refcounted for control flow. If we use differs()
31
+ // semantics, we end with a tailcall to memcmp(). If we use equals() semantics,
32
+ // we need to invert the result that memcmp provides us, which costs several
33
+ // instructions to do so. If we're using the result for control flow (i.e.
34
+ // branching based on the output) then we're just performing the extra
35
+ // operations to invert the result pointlessly. Concretely, we save 6 ops on
36
+ // x86-64/clang with differs().
37
+ int grpc_slice_differs_refcounted(const grpc_slice& a,
38
+ const grpc_slice& b_not_inline);
39
+ // When we compare two slices, and we *know* that one of them is static or
40
+ // interned, we can short circuit our slice equality function. The second slice
41
+ // here must be static or interned; slice a can be any slice, inlined or not.
42
+ inline bool grpc_slice_eq_static_interned(const grpc_slice& a,
43
+ const grpc_slice& b_static_interned) {
44
+ if (a.refcount == b_static_interned.refcount) {
45
+ return true;
46
+ }
47
+ return !grpc_slice_differs_refcounted(a, b_static_interned);
48
+ }
49
+
50
+ #endif /* GRPC_CORE_LIB_SLICE_SLICE_UTILS_H */
@@ -47,7 +47,7 @@ class SliceWeakHashTable : public RefCounted<SliceWeakHashTable<T, Size>> {
47
47
  /// Add a mapping from \a key to \a value, taking ownership of \a key. This
48
48
  /// operation will always succeed. It may discard older entries.
49
49
  void Add(const grpc_slice& key, T value) {
50
- const size_t idx = grpc_slice_hash(key) % Size;
50
+ const size_t idx = grpc_slice_hash_internal(key) % Size;
51
51
  entries_[idx].Set(key, std::move(value));
52
52
  return;
53
53
  }
@@ -55,7 +55,7 @@ class SliceWeakHashTable : public RefCounted<SliceWeakHashTable<T, Size>> {
55
55
  /// Returns the value from the table associated with / \a key or null if not
56
56
  /// found.
57
57
  const T* Get(const grpc_slice& key) const {
58
- const size_t idx = grpc_slice_hash(key) % Size;
58
+ const size_t idx = grpc_slice_hash_internal(key) % Size;
59
59
  const auto& entry = entries_[idx];
60
60
  return grpc_slice_eq(entry.key(), key) ? entry.value() : nullptr;
61
61
  }
@@ -42,8 +42,8 @@
42
42
  #include "src/core/lib/gprpp/ref_counted.h"
43
43
  #include "src/core/lib/iomgr/timer.h"
44
44
  #include "src/core/lib/profiling/timers.h"
45
- #include "src/core/lib/slice/slice_internal.h"
46
45
  #include "src/core/lib/slice/slice_string_helpers.h"
46
+ #include "src/core/lib/slice/slice_utils.h"
47
47
  #include "src/core/lib/surface/api_trace.h"
48
48
  #include "src/core/lib/surface/call.h"
49
49
  #include "src/core/lib/surface/call_test_only.h"
@@ -74,7 +74,7 @@
74
74
  #define ESTIMATED_MDELEM_COUNT 16
75
75
 
76
76
  struct batch_control {
77
- batch_control() { gpr_ref_init(&steps_to_complete, 0); }
77
+ batch_control() = default;
78
78
 
79
79
  grpc_call* call = nullptr;
80
80
  grpc_transport_stream_op_batch op;
@@ -99,8 +99,14 @@ struct batch_control {
99
99
  } completion_data;
100
100
  grpc_closure start_batch;
101
101
  grpc_closure finish_batch;
102
- gpr_refcount steps_to_complete;
102
+ grpc_core::Atomic<intptr_t> steps_to_complete;
103
103
  gpr_atm batch_error = reinterpret_cast<gpr_atm>(GRPC_ERROR_NONE);
104
+ void set_num_steps_to_complete(uintptr_t steps) {
105
+ steps_to_complete.Store(steps, grpc_core::MemoryOrder::RELEASE);
106
+ }
107
+ bool completed_batch_step() {
108
+ return steps_to_complete.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1;
109
+ }
104
110
  };
105
111
 
106
112
  struct parent_call {
@@ -349,8 +355,8 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args,
349
355
  MAX_SEND_EXTRA_METADATA_COUNT);
350
356
  for (size_t i = 0; i < args->add_initial_metadata_count; i++) {
351
357
  call->send_extra_metadata[i].md = args->add_initial_metadata[i];
352
- if (grpc_slice_eq(GRPC_MDKEY(args->add_initial_metadata[i]),
353
- GRPC_MDSTR_PATH)) {
358
+ if (grpc_slice_eq_static_interned(
359
+ GRPC_MDKEY(args->add_initial_metadata[i]), GRPC_MDSTR_PATH)) {
354
360
  path = grpc_slice_ref_internal(
355
361
  GRPC_MDVALUE(args->add_initial_metadata[i]));
356
362
  }
@@ -899,7 +905,7 @@ static int prepare_application_metadata(grpc_call* call, int count,
899
905
  if (!GRPC_LOG_IF_ERROR("validate_metadata",
900
906
  grpc_validate_header_key_is_legal(md->key))) {
901
907
  break;
902
- } else if (!grpc_is_binary_header(md->key) &&
908
+ } else if (!grpc_is_binary_header_internal(md->key) &&
903
909
  !GRPC_LOG_IF_ERROR(
904
910
  "validate_metadata",
905
911
  grpc_validate_header_nonbin_value_is_legal(md->value))) {
@@ -1225,7 +1231,7 @@ static void post_batch_completion(batch_control* bctl) {
1225
1231
  }
1226
1232
 
1227
1233
  static void finish_batch_step(batch_control* bctl) {
1228
- if (GPR_UNLIKELY(gpr_unref(&bctl->steps_to_complete))) {
1234
+ if (GPR_UNLIKELY(bctl->completed_batch_step())) {
1229
1235
  post_batch_completion(bctl);
1230
1236
  }
1231
1237
  }
@@ -1866,7 +1872,7 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
1866
1872
  if (!is_notify_tag_closure) {
1867
1873
  GPR_ASSERT(grpc_cq_begin_op(call->cq, notify_tag));
1868
1874
  }
1869
- gpr_ref_init(&bctl->steps_to_complete, (has_send_ops ? 1 : 0) + num_recv_ops);
1875
+ bctl->set_num_steps_to_complete((has_send_ops ? 1 : 0) + num_recv_ops);
1870
1876
 
1871
1877
  if (has_send_ops) {
1872
1878
  GRPC_CLOSURE_INIT(&bctl->finish_batch, finish_batch, bctl,