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.

Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +487 -649
  3. data/include/grpc/grpc_security.h +25 -0
  4. data/include/grpc/impl/codegen/grpc_types.h +11 -2
  5. data/include/grpc/impl/codegen/port_platform.h +12 -0
  6. data/src/core/ext/filters/client_channel/backup_poller.cc +4 -2
  7. data/src/core/ext/filters/client_channel/client_channel.cc +477 -182
  8. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +25 -16
  9. data/src/core/ext/filters/client_channel/client_channel_channelz.h +11 -6
  10. data/src/core/ext/filters/client_channel/connector.h +10 -2
  11. data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -3
  12. data/src/core/ext/filters/client_channel/http_proxy.cc +9 -10
  13. data/src/core/ext/filters/client_channel/lb_policy.cc +2 -17
  14. data/src/core/ext/filters/client_channel/lb_policy.h +36 -8
  15. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +22 -8
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +86 -52
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +7 -0
  18. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +73 -72
  19. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +8 -12
  20. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +25 -101
  21. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +5 -5
  22. data/src/core/ext/filters/client_channel/parse_address.cc +29 -26
  23. data/src/core/ext/filters/client_channel/resolver.h +3 -11
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +5 -3
  25. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +405 -82
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +44 -51
  27. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +0 -1
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +0 -1
  29. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +11 -6
  30. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +130 -65
  31. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +8 -3
  32. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +31 -14
  33. data/src/core/ext/filters/client_channel/resolver_factory.h +4 -0
  34. data/src/core/ext/filters/client_channel/resolver_registry.cc +11 -0
  35. data/src/core/ext/filters/client_channel/resolver_registry.h +3 -0
  36. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +10 -49
  37. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +1 -14
  38. data/src/core/ext/filters/client_channel/retry_throttle.h +2 -3
  39. data/src/core/ext/filters/client_channel/subchannel.cc +65 -58
  40. data/src/core/ext/filters/client_channel/subchannel.h +65 -45
  41. data/src/core/ext/filters/client_channel/subchannel_interface.h +15 -30
  42. data/src/core/ext/filters/client_idle/client_idle_filter.cc +262 -0
  43. data/src/core/ext/filters/http/client/http_client_filter.cc +4 -5
  44. data/src/core/ext/filters/http/client_authority_filter.cc +2 -2
  45. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +140 -152
  46. data/src/core/ext/filters/max_age/max_age_filter.cc +3 -3
  47. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +3 -4
  48. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +7 -6
  49. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +63 -38
  50. data/src/core/ext/transport/chttp2/transport/context_list.cc +3 -1
  51. data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -4
  52. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +1 -1
  53. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -0
  54. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +8 -0
  55. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +7 -0
  56. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +1 -0
  57. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +37 -22
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +136 -81
  59. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -0
  60. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +7 -166
  61. data/src/core/ext/transport/chttp2/transport/hpack_table.h +41 -15
  62. data/src/core/ext/transport/chttp2/transport/internal.h +13 -2
  63. data/src/core/ext/transport/chttp2/transport/parsing.cc +35 -22
  64. data/src/core/ext/transport/chttp2/transport/stream_map.cc +28 -18
  65. data/src/core/ext/transport/chttp2/transport/writing.cc +1 -0
  66. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
  67. data/src/core/lib/channel/channelz.cc +80 -33
  68. data/src/core/lib/channel/channelz.h +28 -13
  69. data/src/core/lib/compression/compression.cc +1 -2
  70. data/src/core/lib/compression/compression_args.cc +13 -6
  71. data/src/core/lib/compression/compression_args.h +3 -2
  72. data/src/core/lib/compression/compression_internal.cc +1 -1
  73. data/src/core/lib/gpr/env_linux.cc +10 -21
  74. data/src/core/lib/gpr/env_posix.cc +0 -5
  75. data/src/core/lib/gpr/string.cc +7 -2
  76. data/src/core/lib/gpr/string.h +1 -0
  77. data/src/core/lib/gpr/sync_posix.cc +0 -129
  78. data/src/core/lib/gprpp/debug_location.h +3 -2
  79. data/src/core/lib/gprpp/fork.cc +14 -21
  80. data/src/core/lib/gprpp/fork.h +15 -4
  81. data/src/core/lib/gprpp/host_port.cc +118 -0
  82. data/src/core/lib/{gpr → gprpp}/host_port.h +27 -11
  83. data/src/core/lib/gprpp/map.h +25 -0
  84. data/src/core/lib/gprpp/memory.h +26 -9
  85. data/src/core/lib/gprpp/ref_counted.h +63 -21
  86. data/src/core/lib/gprpp/string_view.h +143 -0
  87. data/src/core/lib/gprpp/thd.h +10 -1
  88. data/src/core/lib/gprpp/thd_posix.cc +25 -0
  89. data/src/core/lib/gprpp/thd_windows.cc +9 -1
  90. data/src/core/lib/http/httpcli_security_connector.cc +3 -1
  91. data/src/core/lib/iomgr/cfstream_handle.cc +6 -1
  92. data/src/core/lib/iomgr/cfstream_handle.h +8 -2
  93. data/src/core/lib/iomgr/combiner.cc +4 -4
  94. data/src/core/lib/iomgr/error.cc +18 -8
  95. data/src/core/lib/iomgr/error.h +2 -0
  96. data/src/core/lib/iomgr/ev_posix.cc +4 -2
  97. data/src/core/lib/iomgr/executor.cc +4 -1
  98. data/src/core/lib/iomgr/executor/mpmcqueue.cc +183 -0
  99. data/src/core/lib/iomgr/executor/mpmcqueue.h +178 -0
  100. data/src/core/lib/iomgr/executor/threadpool.cc +138 -0
  101. data/src/core/lib/iomgr/executor/threadpool.h +153 -0
  102. data/src/core/lib/iomgr/fork_posix.cc +4 -2
  103. data/src/core/lib/iomgr/iocp_windows.cc +2 -2
  104. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +14 -0
  105. data/src/core/lib/iomgr/iomgr_uv.cc +3 -0
  106. data/src/core/lib/iomgr/lockfree_event.cc +3 -3
  107. data/src/core/lib/iomgr/resolve_address_custom.cc +16 -20
  108. data/src/core/lib/iomgr/resolve_address_posix.cc +8 -10
  109. data/src/core/lib/iomgr/resolve_address_windows.cc +6 -8
  110. data/src/core/lib/iomgr/sockaddr_utils.cc +5 -3
  111. data/src/core/lib/iomgr/socket_utils_common_posix.cc +0 -1
  112. data/src/core/lib/iomgr/socket_windows.h +1 -1
  113. data/src/core/lib/iomgr/tcp_client_cfstream.cc +7 -6
  114. data/src/core/lib/iomgr/tcp_client_custom.cc +1 -0
  115. data/src/core/lib/iomgr/tcp_custom.cc +4 -0
  116. data/src/core/lib/iomgr/tcp_posix.cc +8 -2
  117. data/src/core/lib/iomgr/tcp_server_custom.cc +1 -0
  118. data/src/core/lib/iomgr/tcp_server_windows.cc +1 -1
  119. data/src/core/lib/iomgr/tcp_windows.cc +7 -7
  120. data/src/core/lib/iomgr/timer_custom.cc +1 -0
  121. data/src/core/lib/iomgr/timer_manager.cc +0 -29
  122. data/src/core/lib/security/credentials/credentials.cc +84 -0
  123. data/src/core/lib/security/credentials/credentials.h +58 -2
  124. data/src/core/lib/security/credentials/jwt/json_token.cc +6 -2
  125. data/src/core/lib/security/credentials/jwt/json_token.h +1 -1
  126. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +245 -24
  127. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +16 -0
  128. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +3 -2
  129. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +21 -25
  130. data/src/core/lib/security/security_connector/local/local_security_connector.cc +3 -2
  131. data/src/core/lib/security/security_connector/security_connector.cc +1 -1
  132. data/src/core/lib/security/security_connector/security_connector.h +1 -1
  133. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +19 -19
  134. data/src/core/lib/security/security_connector/ssl_utils.cc +26 -31
  135. data/src/core/lib/security/security_connector/ssl_utils.h +11 -8
  136. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +16 -20
  137. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +4 -3
  138. data/src/core/lib/security/transport/client_auth_filter.cc +1 -2
  139. data/src/core/lib/security/util/json_util.cc +19 -5
  140. data/src/core/lib/security/util/json_util.h +3 -1
  141. data/src/core/lib/slice/slice.cc +69 -50
  142. data/src/core/lib/slice/slice_buffer.cc +6 -5
  143. data/src/core/lib/slice/slice_hash_table.h +3 -7
  144. data/src/core/lib/slice/slice_intern.cc +130 -39
  145. data/src/core/lib/slice/slice_internal.h +8 -0
  146. data/src/core/lib/slice/slice_utils.h +120 -0
  147. data/src/core/lib/slice/slice_weak_hash_table.h +2 -7
  148. data/src/core/lib/surface/call.cc +8 -3
  149. data/src/core/lib/surface/channel.cc +31 -8
  150. data/src/core/lib/surface/completion_queue.cc +17 -7
  151. data/src/core/lib/surface/init_secure.cc +4 -1
  152. data/src/core/lib/surface/lame_client.cc +2 -2
  153. data/src/core/lib/surface/server.cc +34 -35
  154. data/src/core/lib/surface/server.h +8 -17
  155. data/src/core/lib/surface/version.cc +1 -1
  156. data/src/core/lib/transport/byte_stream.cc +3 -5
  157. data/src/core/lib/transport/byte_stream.h +1 -2
  158. data/src/core/lib/transport/error_utils.cc +10 -1
  159. data/src/core/lib/transport/metadata.cc +202 -35
  160. data/src/core/lib/transport/metadata.h +81 -6
  161. data/src/core/lib/transport/static_metadata.cc +1257 -465
  162. data/src/core/lib/transport/static_metadata.h +190 -347
  163. data/src/core/lib/transport/timeout_encoding.cc +7 -0
  164. data/src/core/lib/transport/timeout_encoding.h +3 -2
  165. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  166. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +0 -1
  167. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -7
  168. data/src/core/tsi/ssl_transport_security.cc +35 -43
  169. data/src/core/tsi/ssl_transport_security.h +2 -1
  170. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  171. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  172. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  173. data/src/ruby/lib/grpc/grpc.rb +1 -1
  174. data/src/ruby/lib/grpc/version.rb +1 -1
  175. metadata +39 -33
  176. data/src/core/lib/gpr/host_port.cc +0 -98
@@ -53,7 +53,8 @@ class SpiffeChannelSecurityConnector final
53
53
 
54
54
  int cmp(const grpc_security_connector* other_sc) const override;
55
55
 
56
- bool check_call_host(const char* host, grpc_auth_context* auth_context,
56
+ bool check_call_host(grpc_core::StringView host,
57
+ grpc_auth_context* auth_context,
57
58
  grpc_closure* on_call_host_checked,
58
59
  grpc_error** error) override;
59
60
 
@@ -83,8 +84,8 @@ class SpiffeChannelSecurityConnector final
83
84
  grpc_tls_server_authorization_check_arg* arg);
84
85
 
85
86
  grpc_closure* on_peer_checked_;
86
- char* target_name_;
87
- char* overridden_target_name_;
87
+ grpc_core::UniquePtr<char> target_name_;
88
+ grpc_core::UniquePtr<char> overridden_target_name_;
88
89
  tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr;
89
90
  grpc_tls_server_authorization_check_arg* check_arg_;
90
91
  };
@@ -346,7 +346,7 @@ static void auth_start_transport_stream_op_batch(
346
346
  GRPC_CALL_STACK_REF(calld->owning_call, "check_call_host");
347
347
  GRPC_CLOSURE_INIT(&calld->async_result_closure, on_host_checked, batch,
348
348
  grpc_schedule_on_exec_ctx);
349
- char* call_host = grpc_slice_to_c_string(calld->host);
349
+ grpc_core::StringView call_host(calld->host);
350
350
  grpc_error* error = GRPC_ERROR_NONE;
351
351
  if (chand->security_connector->check_call_host(
352
352
  call_host, chand->auth_context.get(),
@@ -360,7 +360,6 @@ static void auth_start_transport_stream_op_batch(
360
360
  &calld->check_call_host_cancel_closure, cancel_check_call_host,
361
361
  elem, grpc_schedule_on_exec_ctx));
362
362
  }
363
- gpr_free(call_host);
364
363
  return; /* early exit */
365
364
  }
366
365
  }
@@ -18,6 +18,7 @@
18
18
 
19
19
  #include <grpc/support/port_platform.h>
20
20
 
21
+ #include "src/core/lib/iomgr/error.h"
21
22
  #include "src/core/lib/security/util/json_util.h"
22
23
 
23
24
  #include <string.h>
@@ -26,17 +27,27 @@
26
27
  #include <grpc/support/string_util.h>
27
28
 
28
29
  const char* grpc_json_get_string_property(const grpc_json* json,
29
- const char* prop_name) {
30
- grpc_json* child;
30
+ const char* prop_name,
31
+ grpc_error** error) {
32
+ grpc_json* child = nullptr;
33
+ if (error != nullptr) *error = GRPC_ERROR_NONE;
31
34
  for (child = json->child; child != nullptr; child = child->next) {
32
35
  if (child->key == nullptr) {
33
- gpr_log(GPR_ERROR, "Invalid (null) JSON key encountered");
36
+ if (error != nullptr) {
37
+ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
38
+ "Invalid (null) JSON key encountered");
39
+ }
34
40
  return nullptr;
35
41
  }
36
42
  if (strcmp(child->key, prop_name) == 0) break;
37
43
  }
38
44
  if (child == nullptr || child->type != GRPC_JSON_STRING) {
39
- gpr_log(GPR_ERROR, "Invalid or missing %s property.", prop_name);
45
+ if (error != nullptr) {
46
+ char* error_msg;
47
+ gpr_asprintf(&error_msg, "Invalid or missing %s property.", prop_name);
48
+ *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
49
+ gpr_free(error_msg);
50
+ }
40
51
  return nullptr;
41
52
  }
42
53
  return child->value;
@@ -45,7 +56,10 @@ const char* grpc_json_get_string_property(const grpc_json* json,
45
56
  bool grpc_copy_json_string_property(const grpc_json* json,
46
57
  const char* prop_name,
47
58
  char** copied_value) {
48
- const char* prop_value = grpc_json_get_string_property(json, prop_name);
59
+ grpc_error* error = GRPC_ERROR_NONE;
60
+ const char* prop_value =
61
+ grpc_json_get_string_property(json, prop_name, &error);
62
+ GRPC_LOG_IF_ERROR("Could not copy JSON property", error);
49
63
  if (prop_value == nullptr) return false;
50
64
  *copied_value = gpr_strdup(prop_value);
51
65
  return true;
@@ -23,6 +23,7 @@
23
23
 
24
24
  #include <stdbool.h>
25
25
 
26
+ #include "src/core/lib/iomgr/error.h"
26
27
  #include "src/core/lib/json/json.h"
27
28
 
28
29
  // Constants.
@@ -32,7 +33,8 @@
32
33
 
33
34
  // Gets a child property from a json node.
34
35
  const char* grpc_json_get_string_property(const grpc_json* json,
35
- const char* prop_name);
36
+ const char* prop_name,
37
+ grpc_error** error);
36
38
 
37
39
  // Copies the value of the json child property specified by prop_name.
38
40
  // Returns false if the property was not found.
@@ -37,12 +37,7 @@ char* grpc_slice_to_c_string(grpc_slice slice) {
37
37
  return out;
38
38
  }
39
39
 
40
- grpc_slice grpc_empty_slice(void) {
41
- grpc_slice out;
42
- out.refcount = nullptr;
43
- out.data.inlined.length = 0;
44
- return out;
45
- }
40
+ grpc_slice grpc_empty_slice(void) { return grpc_core::UnmanagedMemorySlice(); }
46
41
 
47
42
  grpc_slice grpc_slice_copy(grpc_slice s) {
48
43
  grpc_slice out = GRPC_SLICE_MALLOC(GRPC_SLICE_LENGTH(s));
@@ -66,32 +61,13 @@ void grpc_slice_unref(grpc_slice slice) {
66
61
  }
67
62
  }
68
63
 
64
+ namespace grpc_core {
65
+
69
66
  /* grpc_slice_from_static_string support structure - a refcount that does
70
67
  nothing */
71
- static grpc_slice_refcount NoopRefcount =
72
- grpc_slice_refcount(grpc_slice_refcount::Type::NOP);
73
-
74
- size_t grpc_slice_memory_usage(grpc_slice s) {
75
- if (s.refcount == nullptr || s.refcount == &NoopRefcount) {
76
- return 0;
77
- } else {
78
- return s.data.refcounted.length;
79
- }
80
- }
81
-
82
- grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) {
83
- grpc_slice slice;
84
- slice.refcount = &NoopRefcount;
85
- slice.data.refcounted.bytes = (uint8_t*)s;
86
- slice.data.refcounted.length = len;
87
- return slice;
88
- }
89
-
90
- grpc_slice grpc_slice_from_static_string(const char* s) {
91
- return grpc_slice_from_static_buffer(s, strlen(s));
92
- }
93
-
94
- namespace grpc_core {
68
+ grpc_slice_refcount kNoopRefcount(grpc_slice_refcount::Type::NOP);
69
+ static_assert(std::is_trivially_destructible<decltype(kNoopRefcount)>::value,
70
+ "kNoopRefcount must be trivially destructible.");
95
71
 
96
72
  /* grpc_slice_new support structures - we create a refcount object extended
97
73
  with the user provided data pointer & destroy function */
@@ -122,6 +98,22 @@ class NewSliceRefcount {
122
98
 
123
99
  } // namespace grpc_core
124
100
 
101
+ size_t grpc_slice_memory_usage(grpc_slice s) {
102
+ if (s.refcount == nullptr || s.refcount == &grpc_core::kNoopRefcount) {
103
+ return 0;
104
+ } else {
105
+ return s.data.refcounted.length;
106
+ }
107
+ }
108
+
109
+ grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) {
110
+ return grpc_core::ExternallyManagedSlice(s, len);
111
+ }
112
+
113
+ grpc_slice grpc_slice_from_static_string(const char* s) {
114
+ return grpc_core::ExternallyManagedSlice(s, strlen(s));
115
+ }
116
+
125
117
  grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
126
118
  void (*destroy)(void*),
127
119
  void* user_data) {
@@ -205,15 +197,29 @@ grpc_slice grpc_slice_new_with_len(void* p, size_t len,
205
197
  return slice;
206
198
  }
207
199
 
200
+ grpc_core::UnmanagedMemorySlice::UnmanagedMemorySlice(const char* source,
201
+ size_t length) {
202
+ if (length <= sizeof(data.inlined.bytes)) {
203
+ refcount = nullptr;
204
+ data.inlined.length = static_cast<uint8_t>(length);
205
+ } else {
206
+ HeapInit(length);
207
+ }
208
+ if (length > 0) {
209
+ memcpy(GRPC_SLICE_START_PTR(*this), source, length);
210
+ }
211
+ }
212
+
213
+ grpc_core::UnmanagedMemorySlice::UnmanagedMemorySlice(const char* source)
214
+ : grpc_core::UnmanagedMemorySlice::UnmanagedMemorySlice(source,
215
+ strlen(source)) {}
216
+
208
217
  grpc_slice grpc_slice_from_copied_buffer(const char* source, size_t length) {
209
- if (length == 0) return grpc_empty_slice();
210
- grpc_slice slice = GRPC_SLICE_MALLOC(length);
211
- memcpy(GRPC_SLICE_START_PTR(slice), source, length);
212
- return slice;
218
+ return grpc_core::UnmanagedMemorySlice(source, length);
213
219
  }
214
220
 
215
221
  grpc_slice grpc_slice_from_copied_string(const char* source) {
216
- return grpc_slice_from_copied_buffer(source, strlen(source));
222
+ return grpc_core::UnmanagedMemorySlice(source, strlen(source));
217
223
  }
218
224
 
219
225
  grpc_slice grpc_slice_from_moved_buffer(grpc_core::UniquePtr<char> p,
@@ -264,8 +270,11 @@ class MallocRefCount {
264
270
  } // namespace
265
271
 
266
272
  grpc_slice grpc_slice_malloc_large(size_t length) {
267
- grpc_slice slice;
273
+ return grpc_core::UnmanagedMemorySlice(
274
+ length, grpc_core::UnmanagedMemorySlice::ForceHeapAllocation());
275
+ }
268
276
 
277
+ void grpc_core::UnmanagedMemorySlice::HeapInit(size_t length) {
269
278
  /* Memory layout used by the slice created here:
270
279
 
271
280
  +-----------+----------------------------------------------------------+
@@ -284,29 +293,30 @@ grpc_slice grpc_slice_malloc_large(size_t length) {
284
293
 
285
294
  /* Build up the slice to be returned. */
286
295
  /* The slices refcount points back to the allocated block. */
287
- slice.refcount = rc->base_refcount();
296
+ refcount = rc->base_refcount();
288
297
  /* The data bytes are placed immediately after the refcount struct */
289
- slice.data.refcounted.bytes = reinterpret_cast<uint8_t*>(rc + 1);
298
+ data.refcounted.bytes = reinterpret_cast<uint8_t*>(rc + 1);
290
299
  /* And the length of the block is set to the requested length */
291
- slice.data.refcounted.length = length;
292
- return slice;
300
+ data.refcounted.length = length;
293
301
  }
294
302
 
295
303
  grpc_slice grpc_slice_malloc(size_t length) {
296
- grpc_slice slice;
304
+ return grpc_core::UnmanagedMemorySlice(length);
305
+ }
297
306
 
298
- if (length > sizeof(slice.data.inlined.bytes)) {
299
- return grpc_slice_malloc_large(length);
307
+ grpc_core::UnmanagedMemorySlice::UnmanagedMemorySlice(size_t length) {
308
+ if (length > sizeof(data.inlined.bytes)) {
309
+ HeapInit(length);
300
310
  } else {
301
311
  /* small slice: just inline the data */
302
- slice.refcount = nullptr;
303
- slice.data.inlined.length = static_cast<uint8_t>(length);
312
+ refcount = nullptr;
313
+ data.inlined.length = static_cast<uint8_t>(length);
304
314
  }
305
- return slice;
306
315
  }
307
316
 
308
- grpc_slice grpc_slice_sub_no_ref(grpc_slice source, size_t begin, size_t end) {
309
- grpc_slice subset;
317
+ template <typename Slice>
318
+ static Slice sub_no_ref(const Slice& source, size_t begin, size_t end) {
319
+ Slice subset;
310
320
 
311
321
  GPR_ASSERT(end >= begin);
312
322
 
@@ -330,6 +340,15 @@ grpc_slice grpc_slice_sub_no_ref(grpc_slice source, size_t begin, size_t end) {
330
340
  return subset;
331
341
  }
332
342
 
343
+ grpc_slice grpc_slice_sub_no_ref(grpc_slice source, size_t begin, size_t end) {
344
+ return sub_no_ref(source, begin, end);
345
+ }
346
+
347
+ grpc_core::UnmanagedMemorySlice grpc_slice_sub_no_ref(
348
+ const grpc_core::UnmanagedMemorySlice& source, size_t begin, size_t end) {
349
+ return sub_no_ref(source, begin, end);
350
+ }
351
+
333
352
  grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) {
334
353
  grpc_slice subset;
335
354
 
@@ -375,10 +394,10 @@ grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice* source, size_t split,
375
394
  switch (ref_whom) {
376
395
  case GRPC_SLICE_REF_TAIL:
377
396
  tail.refcount = source->refcount->sub_refcount();
378
- source->refcount = &NoopRefcount;
397
+ source->refcount = &grpc_core::kNoopRefcount;
379
398
  break;
380
399
  case GRPC_SLICE_REF_HEAD:
381
- tail.refcount = &NoopRefcount;
400
+ tail.refcount = &grpc_core::kNoopRefcount;
382
401
  source->refcount = source->refcount->sub_refcount();
383
402
  break;
384
403
  case GRPC_SLICE_REF_BOTH:
@@ -103,7 +103,7 @@ uint8_t* grpc_slice_buffer_tiny_add(grpc_slice_buffer* sb, size_t n) {
103
103
 
104
104
  sb->length += n;
105
105
 
106
- if (sb->count == 0) goto add_new;
106
+ if (sb->count == 0) goto add_first;
107
107
  back = &sb->slices[sb->count - 1];
108
108
  if (back->refcount) goto add_new;
109
109
  if ((back->data.inlined.length + n) > sizeof(back->data.inlined.bytes))
@@ -115,6 +115,7 @@ uint8_t* grpc_slice_buffer_tiny_add(grpc_slice_buffer* sb, size_t n) {
115
115
 
116
116
  add_new:
117
117
  maybe_embiggen(sb);
118
+ add_first:
118
119
  back = &sb->slices[sb->count];
119
120
  sb->count++;
120
121
  back->refcount = nullptr;
@@ -262,9 +263,9 @@ void grpc_slice_buffer_move_into(grpc_slice_buffer* src,
262
263
  src->length = 0;
263
264
  }
264
265
 
266
+ template <bool incref>
265
267
  static void slice_buffer_move_first_maybe_ref(grpc_slice_buffer* src, size_t n,
266
- grpc_slice_buffer* dst,
267
- bool incref) {
268
+ grpc_slice_buffer* dst) {
268
269
  GPR_ASSERT(src->length >= n);
269
270
  if (src->length == n) {
270
271
  grpc_slice_buffer_move_into(src, dst);
@@ -304,12 +305,12 @@ static void slice_buffer_move_first_maybe_ref(grpc_slice_buffer* src, size_t n,
304
305
 
305
306
  void grpc_slice_buffer_move_first(grpc_slice_buffer* src, size_t n,
306
307
  grpc_slice_buffer* dst) {
307
- slice_buffer_move_first_maybe_ref(src, n, dst, true);
308
+ slice_buffer_move_first_maybe_ref<true>(src, n, dst);
308
309
  }
309
310
 
310
311
  void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer* src, size_t n,
311
312
  grpc_slice_buffer* dst) {
312
- slice_buffer_move_first_maybe_ref(src, n, dst, false);
313
+ slice_buffer_move_first_maybe_ref<false>(src, n, dst);
313
314
  }
314
315
 
315
316
  void grpc_slice_buffer_move_first_into_buffer(grpc_slice_buffer* src, size_t n,
@@ -25,6 +25,7 @@
25
25
  #include <grpc/support/log.h>
26
26
 
27
27
  #include "src/core/lib/gpr/useful.h"
28
+ #include "src/core/lib/gprpp/memory.h"
28
29
  #include "src/core/lib/gprpp/ref_counted.h"
29
30
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
30
31
  #include "src/core/lib/slice/slice_internal.h"
@@ -77,13 +78,8 @@ class SliceHashTable : public RefCounted<SliceHashTable<T>> {
77
78
  static int Cmp(const SliceHashTable& a, const SliceHashTable& b);
78
79
 
79
80
  private:
80
- // So New() can call our private ctor.
81
- template <typename T2, typename... Args>
82
- friend T2* New(Args&&... args);
83
-
84
- // So Delete() can call our private dtor.
85
- template <typename T2>
86
- friend void Delete(T2*);
81
+ GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
82
+ GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
87
83
 
88
84
  SliceHashTable(size_t num_entries, Entry* entries, ValueCmp value_cmp);
89
85
  virtual ~SliceHashTable();
@@ -107,12 +107,10 @@ static void grow_shard(slice_shard* shard) {
107
107
  shard->capacity = capacity;
108
108
  }
109
109
 
110
- static grpc_slice materialize(InternedSliceRefcount* s) {
111
- grpc_slice slice;
112
- slice.refcount = &s->base;
113
- slice.data.refcounted.bytes = reinterpret_cast<uint8_t*>(s + 1);
114
- slice.data.refcounted.length = s->length;
115
- return slice;
110
+ grpc_core::InternedSlice::InternedSlice(InternedSliceRefcount* s) {
111
+ refcount = &s->base;
112
+ data.refcounted.bytes = reinterpret_cast<uint8_t*>(s + 1);
113
+ data.refcounted.length = s->length;
116
114
  }
117
115
 
118
116
  uint32_t grpc_slice_default_hash_impl(grpc_slice s) {
@@ -152,57 +150,150 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice,
152
150
  }
153
151
 
154
152
  grpc_slice grpc_slice_intern(grpc_slice slice) {
155
- GPR_TIMER_SCOPE("grpc_slice_intern", 0);
156
- if (GRPC_IS_STATIC_METADATA_STRING(slice)) {
157
- return slice;
158
- }
159
-
160
- uint32_t hash = grpc_slice_hash_internal(slice);
153
+ /* TODO(arjunroy): At present, this is capable of returning either a static or
154
+ an interned slice. This yields weirdness like the constructor for
155
+ ManagedMemorySlice instantiating itself as an instance of a derived type
156
+ (StaticMetadataSlice or InternedSlice). Should reexamine. */
157
+ return grpc_core::ManagedMemorySlice(&slice);
158
+ }
161
159
 
160
+ // Attempt to see if the provided slice or string matches a static slice.
161
+ // SliceArgs... is either a const grpc_slice& or a string and length. In either
162
+ // case, hash is the pre-computed hash value.
163
+ //
164
+ // Returns: a matching static slice, or null.
165
+ template <class... SliceArgs>
166
+ static const grpc_core::StaticMetadataSlice* MatchStaticSlice(
167
+ uint32_t hash, SliceArgs&&... args) {
162
168
  for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
163
169
  static_metadata_hash_ent ent =
164
170
  static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
165
171
  if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
166
- grpc_slice_eq_static_interned(slice,
167
- grpc_static_slice_table[ent.idx])) {
168
- return grpc_static_slice_table[ent.idx];
172
+ grpc_static_slice_table[ent.idx].Equals(
173
+ std::forward<SliceArgs>(args)...)) {
174
+ return &grpc_static_slice_table[ent.idx];
169
175
  }
170
176
  }
177
+ return nullptr;
178
+ }
171
179
 
172
- InternedSliceRefcount* s;
173
- slice_shard* shard = &g_shards[SHARD_IDX(hash)];
180
+ // Helper methods to enable us to select appropriately overloaded slice methods
181
+ // whether we're dealing with a slice, or a buffer with length, when interning
182
+ // strings. Helpers for FindOrCreateInternedSlice().
183
+ static const void* GetBuffer(const void* buf, size_t len) { return buf; }
184
+ static size_t GetLength(const void* buf, size_t len) { return len; }
185
+ static const void* GetBuffer(const grpc_slice& slice) {
186
+ return GRPC_SLICE_START_PTR(slice);
187
+ }
188
+ static size_t GetLength(const grpc_slice& slice) {
189
+ return GRPC_SLICE_LENGTH(slice);
190
+ }
174
191
 
175
- gpr_mu_lock(&shard->mu);
192
+ // Creates an interned slice for a string that does not currently exist in the
193
+ // intern table. SliceArgs... is either a const grpc_slice& or a string and
194
+ // length. In either case, hash is the pre-computed hash value. We must already
195
+ // hold the shard lock. Helper for FindOrCreateInternedSlice().
196
+ //
197
+ // Returns: a newly interned slice.
198
+ template <class... SliceArgs>
199
+ static InternedSliceRefcount* InternNewStringLocked(slice_shard* shard,
200
+ size_t shard_idx,
201
+ uint32_t hash,
202
+ SliceArgs&&... args) {
203
+ /* string data goes after the internal_string header */
204
+ size_t len = GetLength(std::forward<SliceArgs>(args)...);
205
+ const void* buffer = GetBuffer(std::forward<SliceArgs>(args)...);
206
+ InternedSliceRefcount* s =
207
+ static_cast<InternedSliceRefcount*>(gpr_malloc(sizeof(*s) + len));
208
+ new (s) grpc_core::InternedSliceRefcount(len, hash, shard->strs[shard_idx]);
209
+ memcpy(reinterpret_cast<char*>(s + 1), buffer, len);
210
+ shard->strs[shard_idx] = s;
211
+ shard->count++;
212
+ if (shard->count > shard->capacity * 2) {
213
+ grow_shard(shard);
214
+ }
215
+ return s;
216
+ }
176
217
 
218
+ // Attempt to see if the provided slice or string matches an existing interned
219
+ // slice. SliceArgs... is either a const grpc_slice& or a string and length. In
220
+ // either case, hash is the pre-computed hash value. We must already hold the
221
+ // shard lock. Helper for FindOrCreateInternedSlice().
222
+ //
223
+ // Returns: a pre-existing matching static slice, or null.
224
+ template <class... SliceArgs>
225
+ static InternedSliceRefcount* MatchInternedSliceLocked(uint32_t hash,
226
+ size_t idx,
227
+ SliceArgs&&... args) {
228
+ InternedSliceRefcount* s;
229
+ slice_shard* shard = &g_shards[SHARD_IDX(hash)];
177
230
  /* search for an existing string */
178
- size_t idx = TABLE_IDX(hash, shard->capacity);
179
231
  for (s = shard->strs[idx]; s; s = s->bucket_next) {
180
232
  if (s->hash == hash &&
181
- grpc_slice_eq_static_interned(slice, materialize(s))) {
233
+ grpc_core::InternedSlice(s).Equals(std::forward<SliceArgs>(args)...)) {
182
234
  if (s->refcnt.RefIfNonZero()) {
183
- gpr_mu_unlock(&shard->mu);
184
- return materialize(s);
235
+ return s;
185
236
  }
186
237
  }
187
238
  }
239
+ return nullptr;
240
+ }
188
241
 
189
- /* not found: create a new string */
190
- /* string data goes after the internal_string header */
191
- s = static_cast<InternedSliceRefcount*>(
192
- gpr_malloc(sizeof(*s) + GRPC_SLICE_LENGTH(slice)));
193
-
194
- new (s) grpc_core::InternedSliceRefcount(GRPC_SLICE_LENGTH(slice), hash,
195
- shard->strs[idx]);
196
- memcpy(reinterpret_cast<char*>(s + 1), GRPC_SLICE_START_PTR(slice),
197
- GRPC_SLICE_LENGTH(slice));
198
- shard->strs[idx] = s;
199
- shard->count++;
200
- if (shard->count > shard->capacity * 2) {
201
- grow_shard(shard);
242
+ // Attempt to see if the provided slice or string matches an existing interned
243
+ // slice, and failing that, create an interned slice with its contents. Returns
244
+ // either the existing matching interned slice or the newly created one.
245
+ // SliceArgs... is either a const grpc_slice& or a string and length. In either
246
+ // case, hash is the pre-computed hash value. We do not hold the shard lock
247
+ // here, but do take it.
248
+ //
249
+ // Returns: an interned slice, either pre-existing/matched or newly created.
250
+ template <class... SliceArgs>
251
+ static InternedSliceRefcount* FindOrCreateInternedSlice(uint32_t hash,
252
+ SliceArgs&&... args) {
253
+ slice_shard* shard = &g_shards[SHARD_IDX(hash)];
254
+ gpr_mu_lock(&shard->mu);
255
+ const size_t idx = TABLE_IDX(hash, shard->capacity);
256
+ InternedSliceRefcount* s =
257
+ MatchInternedSliceLocked(hash, idx, std::forward<SliceArgs>(args)...);
258
+ if (s == nullptr) {
259
+ s = InternNewStringLocked(shard, idx, hash,
260
+ std::forward<SliceArgs>(args)...);
202
261
  }
203
-
204
262
  gpr_mu_unlock(&shard->mu);
205
- return materialize(s);
263
+ return s;
264
+ }
265
+
266
+ grpc_core::ManagedMemorySlice::ManagedMemorySlice(const char* string)
267
+ : grpc_core::ManagedMemorySlice::ManagedMemorySlice(string,
268
+ strlen(string)) {}
269
+
270
+ grpc_core::ManagedMemorySlice::ManagedMemorySlice(const char* string,
271
+ size_t len) {
272
+ GPR_TIMER_SCOPE("grpc_slice_intern", 0);
273
+ const uint32_t hash = gpr_murmur_hash3(string, len, g_hash_seed);
274
+ const StaticMetadataSlice* static_slice = MatchStaticSlice(hash, string, len);
275
+ if (static_slice) {
276
+ *this = *static_slice;
277
+ } else {
278
+ *this =
279
+ grpc_core::InternedSlice(FindOrCreateInternedSlice(hash, string, len));
280
+ }
281
+ }
282
+
283
+ grpc_core::ManagedMemorySlice::ManagedMemorySlice(const grpc_slice* slice_ptr) {
284
+ GPR_TIMER_SCOPE("grpc_slice_intern", 0);
285
+ const grpc_slice& slice = *slice_ptr;
286
+ if (GRPC_IS_STATIC_METADATA_STRING(slice)) {
287
+ *this = static_cast<const grpc_core::StaticMetadataSlice&>(slice);
288
+ return;
289
+ }
290
+ const uint32_t hash = grpc_slice_hash_internal(slice);
291
+ const StaticMetadataSlice* static_slice = MatchStaticSlice(hash, slice);
292
+ if (static_slice) {
293
+ *this = *static_slice;
294
+ } else {
295
+ *this = grpc_core::InternedSlice(FindOrCreateInternedSlice(hash, slice));
296
+ }
206
297
  }
207
298
 
208
299
  void grpc_test_only_set_slice_hash_seed(uint32_t seed) {
@@ -259,8 +350,8 @@ void grpc_slice_intern_shutdown(void) {
259
350
  shard->count);
260
351
  for (size_t j = 0; j < shard->capacity; j++) {
261
352
  for (InternedSliceRefcount* s = shard->strs[j]; s; s = s->bucket_next) {
262
- char* text =
263
- grpc_dump_slice(materialize(s), GPR_DUMP_HEX | GPR_DUMP_ASCII);
353
+ char* text = grpc_dump_slice(grpc_core::InternedSlice(s),
354
+ GPR_DUMP_HEX | GPR_DUMP_ASCII);
264
355
  gpr_log(GPR_DEBUG, "LEAKED: %s", text);
265
356
  gpr_free(text);
266
357
  }