grpc 1.1.2 → 1.2.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1257 -404
  3. data/etc/roots.pem +189 -102
  4. data/include/grpc/census.h +7 -7
  5. data/include/grpc/compression.h +4 -4
  6. data/include/grpc/grpc.h +13 -7
  7. data/include/grpc/impl/codegen/atm_gcc_atomic.h +26 -9
  8. data/include/grpc/impl/codegen/grpc_types.h +39 -30
  9. data/include/grpc/impl/codegen/slice.h +24 -6
  10. data/include/grpc/impl/codegen/sync.h +8 -0
  11. data/include/grpc/load_reporting.h +63 -0
  12. data/include/grpc/slice.h +37 -1
  13. data/include/grpc/slice_buffer.h +7 -0
  14. data/include/grpc/support/alloc.h +3 -0
  15. data/include/grpc/support/useful.h +3 -0
  16. data/src/core/ext/census/gen/census.pb.h +1 -1
  17. data/src/core/ext/census/gen/trace_context.pb.c +9 -36
  18. data/src/core/ext/census/gen/trace_context.pb.h +20 -26
  19. data/src/core/ext/census/grpc_filter.c +3 -5
  20. data/src/core/ext/census/trace_context.c +1 -1
  21. data/src/core/ext/census/trace_context.h +3 -0
  22. data/src/core/ext/census/trace_label.h +61 -0
  23. data/src/core/ext/census/trace_propagation.h +63 -0
  24. data/src/core/ext/census/trace_status.h +45 -0
  25. data/src/core/ext/census/trace_string.h +50 -0
  26. data/src/core/ext/census/tracing.c +31 -11
  27. data/src/core/ext/census/tracing.h +124 -0
  28. data/src/core/ext/client_channel/client_channel.c +456 -368
  29. data/src/core/ext/client_channel/client_channel.h +4 -0
  30. data/src/core/ext/client_channel/client_channel_plugin.c +6 -1
  31. data/src/core/ext/client_channel/connector.c +3 -3
  32. data/src/core/ext/client_channel/connector.h +4 -3
  33. data/src/core/ext/client_channel/http_connect_handshaker.c +62 -72
  34. data/src/core/ext/client_channel/http_connect_handshaker.h +7 -10
  35. data/src/core/ext/client_channel/http_proxy.c +125 -0
  36. data/src/core/ext/client_channel/http_proxy.h +39 -0
  37. data/src/core/ext/client_channel/lb_policy.c +56 -35
  38. data/src/core/ext/client_channel/lb_policy.h +46 -39
  39. data/src/core/ext/client_channel/lb_policy_factory.h +1 -0
  40. data/src/core/ext/client_channel/parse_address.c +32 -6
  41. data/src/core/ext/client_channel/proxy_mapper.c +63 -0
  42. data/src/core/ext/client_channel/proxy_mapper.h +89 -0
  43. data/src/core/ext/client_channel/proxy_mapper_registry.c +133 -0
  44. data/src/core/ext/client_channel/proxy_mapper_registry.h +59 -0
  45. data/src/core/ext/client_channel/resolver.c +16 -9
  46. data/src/core/ext/client_channel/resolver.h +23 -12
  47. data/src/core/ext/client_channel/resolver_factory.h +1 -0
  48. data/src/core/ext/client_channel/resolver_registry.c +15 -11
  49. data/src/core/ext/client_channel/resolver_registry.h +5 -3
  50. data/src/core/ext/client_channel/subchannel.c +44 -27
  51. data/src/core/ext/client_channel/subchannel.h +6 -2
  52. data/src/core/ext/client_channel/uri_parser.c +26 -14
  53. data/src/core/ext/client_channel/uri_parser.h +3 -1
  54. data/src/core/ext/lb_policy/grpclb/grpclb.c +220 -209
  55. data/src/core/ext/lb_policy/grpclb/grpclb_channel.h +56 -0
  56. data/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c +107 -0
  57. data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +3 -6
  58. data/src/core/ext/lb_policy/pick_first/pick_first.c +71 -116
  59. data/src/core/ext/lb_policy/round_robin/round_robin.c +52 -67
  60. data/src/core/ext/load_reporting/load_reporting.c +20 -0
  61. data/src/core/ext/load_reporting/load_reporting.h +1 -16
  62. data/src/core/ext/load_reporting/load_reporting_filter.c +28 -54
  63. data/src/core/ext/resolver/dns/native/dns_resolver.c +31 -45
  64. data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +20 -29
  65. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +11 -8
  66. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +11 -2
  67. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +143 -46
  68. data/src/core/ext/transport/chttp2/server/chttp2_server.c +12 -50
  69. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +1 -1
  70. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +1 -1
  71. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +7 -7
  72. data/src/core/ext/transport/chttp2/transport/bin_encoder.c +1 -2
  73. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -2
  74. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
  75. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +606 -374
  76. data/src/core/ext/transport/chttp2/transport/frame_ping.c +17 -5
  77. data/src/core/ext/transport/chttp2/transport/frame_ping.h +2 -2
  78. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +9 -13
  79. data/src/core/ext/transport/chttp2/transport/frame_settings.c +12 -11
  80. data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -1
  81. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +5 -6
  82. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +100 -53
  83. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -2
  84. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +126 -70
  85. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +13 -7
  86. data/src/core/ext/transport/chttp2/transport/hpack_table.c +22 -19
  87. data/src/core/ext/transport/chttp2/transport/hpack_table.h +6 -6
  88. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +23 -11
  89. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -2
  90. data/src/core/ext/transport/chttp2/transport/internal.h +169 -42
  91. data/src/core/ext/transport/chttp2/transport/parsing.c +98 -41
  92. data/src/core/ext/transport/chttp2/transport/stream_lists.c +29 -14
  93. data/src/core/ext/transport/chttp2/transport/writing.c +137 -15
  94. data/src/core/lib/channel/channel_stack.c +14 -44
  95. data/src/core/lib/channel/channel_stack.h +10 -17
  96. data/src/core/lib/channel/channel_stack_builder.c +2 -3
  97. data/src/core/lib/channel/compress_filter.c +54 -46
  98. data/src/core/lib/channel/connected_channel.c +4 -4
  99. data/src/core/lib/channel/connected_channel.h +5 -0
  100. data/src/core/lib/channel/context.h +3 -0
  101. data/src/core/lib/channel/deadline_filter.c +61 -61
  102. data/src/core/lib/channel/deadline_filter.h +8 -5
  103. data/src/core/lib/channel/handshaker.c +47 -7
  104. data/src/core/lib/channel/handshaker.h +21 -3
  105. data/src/core/lib/channel/http_client_filter.c +149 -99
  106. data/src/core/lib/channel/http_server_filter.c +163 -147
  107. data/src/core/lib/channel/message_size_filter.c +15 -10
  108. data/src/core/lib/compression/algorithm_metadata.h +4 -4
  109. data/src/core/lib/compression/compression.c +17 -23
  110. data/src/core/lib/http/httpcli.c +3 -2
  111. data/src/core/lib/http/httpcli.h +2 -1
  112. data/src/core/lib/http/httpcli_security_connector.c +2 -3
  113. data/src/core/lib/http/parser.c +2 -2
  114. data/src/core/lib/iomgr/closure.c +6 -3
  115. data/src/core/lib/iomgr/closure.h +4 -2
  116. data/src/core/lib/iomgr/combiner.c +35 -5
  117. data/src/core/lib/iomgr/combiner.h +21 -2
  118. data/src/core/lib/iomgr/endpoint.c +3 -2
  119. data/src/core/lib/iomgr/endpoint.h +3 -2
  120. data/src/core/lib/iomgr/error.c +60 -94
  121. data/src/core/lib/iomgr/error.h +7 -10
  122. data/src/core/lib/iomgr/error_internal.h +54 -0
  123. data/src/core/lib/iomgr/ev_epoll_linux.c +253 -109
  124. data/src/core/lib/iomgr/ev_poll_posix.c +61 -29
  125. data/src/core/lib/iomgr/ev_posix.c +7 -8
  126. data/src/core/lib/iomgr/ev_posix.h +4 -4
  127. data/src/core/lib/iomgr/exec_ctx.c +11 -6
  128. data/src/core/lib/iomgr/exec_ctx.h +11 -14
  129. data/src/core/lib/iomgr/executor.c +2 -2
  130. data/src/core/lib/iomgr/load_file.c +1 -1
  131. data/src/core/lib/iomgr/network_status_tracker.c +5 -81
  132. data/src/core/lib/iomgr/pollset.h +1 -3
  133. data/src/core/lib/iomgr/pollset_set.h +2 -1
  134. data/src/core/lib/iomgr/pollset_set_uv.c +2 -1
  135. data/src/core/lib/iomgr/pollset_set_windows.c +2 -1
  136. data/src/core/lib/iomgr/pollset_uv.c +25 -11
  137. data/src/core/lib/iomgr/pollset_windows.c +0 -11
  138. data/src/core/lib/iomgr/resolve_address_uv.c +50 -2
  139. data/src/core/lib/iomgr/resource_quota.c +41 -11
  140. data/src/core/lib/iomgr/resource_quota.h +6 -0
  141. data/src/core/lib/iomgr/sockaddr_utils.c +33 -17
  142. data/src/core/lib/iomgr/sockaddr_utils.h +4 -0
  143. data/src/core/lib/iomgr/tcp_client_posix.c +2 -3
  144. data/src/core/lib/iomgr/tcp_client_uv.c +1 -3
  145. data/src/core/lib/iomgr/tcp_client_windows.c +21 -6
  146. data/src/core/lib/iomgr/tcp_posix.c +4 -5
  147. data/src/core/lib/iomgr/tcp_server_posix.c +269 -94
  148. data/src/core/lib/iomgr/tcp_server_windows.c +1 -1
  149. data/src/core/lib/iomgr/tcp_uv.c +11 -5
  150. data/src/core/lib/iomgr/tcp_windows.c +20 -7
  151. data/src/core/lib/iomgr/timer_generic.c +15 -22
  152. data/src/core/lib/iomgr/timer_generic.h +1 -1
  153. data/src/core/lib/iomgr/timer_uv.c +10 -6
  154. data/src/core/lib/iomgr/timer_uv.h +1 -1
  155. data/src/core/lib/iomgr/udp_server.c +45 -6
  156. data/src/core/lib/iomgr/udp_server.h +7 -1
  157. data/src/core/lib/iomgr/unix_sockets_posix.c +11 -1
  158. data/src/core/lib/json/json.c +1 -2
  159. data/src/core/lib/profiling/basic_timers.c +17 -3
  160. data/src/core/lib/security/context/security_context.c +3 -10
  161. data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -8
  162. data/src/core/lib/security/credentials/credentials.c +48 -2
  163. data/src/core/lib/security/credentials/credentials.h +13 -0
  164. data/src/core/lib/security/credentials/credentials_metadata.c +1 -2
  165. data/src/core/lib/security/credentials/fake/fake_credentials.c +6 -8
  166. data/src/core/lib/security/credentials/fake/fake_credentials.h +15 -0
  167. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +3 -3
  168. data/src/core/lib/security/credentials/iam/iam_credentials.c +1 -2
  169. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -2
  170. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +5 -8
  171. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
  172. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +3 -5
  173. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +15 -13
  174. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +2 -4
  175. data/src/core/lib/security/transport/client_auth_filter.c +72 -47
  176. data/src/core/lib/security/transport/lb_targets_info.c +70 -0
  177. data/src/core/lib/security/transport/lb_targets_info.h +47 -0
  178. data/src/core/lib/security/transport/secure_endpoint.c +3 -3
  179. data/src/core/lib/security/transport/security_connector.c +125 -28
  180. data/src/core/lib/security/transport/security_connector.h +4 -3
  181. data/src/core/lib/security/transport/security_handshaker.c +13 -9
  182. data/src/core/lib/security/transport/server_auth_filter.c +31 -40
  183. data/src/core/lib/security/util/b64.c +1 -1
  184. data/src/core/lib/slice/slice.c +110 -20
  185. data/src/core/lib/slice/slice_buffer.c +92 -39
  186. data/src/core/lib/{transport/mdstr_hash_table.c → slice/slice_hash_table.c} +40 -33
  187. data/src/core/lib/{transport/mdstr_hash_table.h → slice/slice_hash_table.h} +21 -21
  188. data/src/core/lib/slice/slice_intern.c +346 -0
  189. data/src/core/lib/slice/slice_internal.h +15 -0
  190. data/src/core/lib/slice/slice_string_helpers.c +5 -0
  191. data/src/core/lib/slice/slice_string_helpers.h +5 -0
  192. data/src/core/lib/support/alloc.c +26 -1
  193. data/src/core/lib/support/cmdline.c +2 -4
  194. data/src/core/lib/support/cpu_posix.c +2 -7
  195. data/src/core/lib/support/histogram.c +1 -2
  196. data/src/core/lib/support/log_posix.c +8 -4
  197. data/src/core/lib/support/spinlock.h +52 -0
  198. data/src/core/lib/support/subprocess_posix.c +1 -2
  199. data/src/core/lib/support/sync.c +7 -1
  200. data/src/core/lib/support/sync_posix.c +9 -0
  201. data/src/core/lib/support/time_windows.c +7 -1
  202. data/src/core/lib/surface/call.c +647 -629
  203. data/src/core/lib/surface/call.h +4 -1
  204. data/src/core/lib/surface/call_details.c +8 -2
  205. data/src/core/lib/surface/call_log_batch.c +17 -6
  206. data/src/core/lib/surface/channel.c +49 -59
  207. data/src/core/lib/surface/channel.h +5 -6
  208. data/src/core/lib/surface/completion_queue.c +16 -45
  209. data/src/core/lib/surface/completion_queue.h +0 -3
  210. data/src/core/lib/surface/init.c +6 -2
  211. data/src/core/lib/surface/init_secure.c +1 -1
  212. data/src/core/lib/surface/lame_client.c +14 -4
  213. data/src/core/lib/surface/server.c +79 -82
  214. data/src/core/lib/surface/validate_metadata.c +46 -15
  215. data/src/core/lib/surface/validate_metadata.h +43 -0
  216. data/src/core/lib/surface/version.c +2 -2
  217. data/src/core/lib/transport/bdp_estimator.c +104 -0
  218. data/src/core/lib/transport/bdp_estimator.h +76 -0
  219. data/src/core/lib/transport/connectivity_state.c +33 -13
  220. data/src/core/lib/transport/connectivity_state.h +15 -5
  221. data/src/core/lib/transport/error_utils.c +124 -0
  222. data/src/core/lib/transport/error_utils.h +56 -0
  223. data/src/core/{ext/transport/chttp2 → lib}/transport/http2_errors.h +18 -18
  224. data/src/core/lib/transport/metadata.c +259 -503
  225. data/src/core/lib/transport/metadata.h +69 -68
  226. data/src/core/lib/transport/metadata_batch.c +183 -63
  227. data/src/core/lib/transport/metadata_batch.h +50 -26
  228. data/src/core/lib/transport/pid_controller.c +28 -8
  229. data/src/core/lib/transport/pid_controller.h +15 -2
  230. data/src/core/lib/transport/service_config.c +21 -18
  231. data/src/core/lib/transport/service_config.h +5 -5
  232. data/src/core/lib/transport/static_metadata.c +753 -112
  233. data/src/core/lib/transport/static_metadata.h +403 -264
  234. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.c +18 -20
  235. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.h +9 -10
  236. data/src/core/lib/transport/timeout_encoding.c +11 -9
  237. data/src/core/lib/transport/timeout_encoding.h +3 -1
  238. data/src/core/lib/transport/transport.c +47 -87
  239. data/src/core/lib/transport/transport.h +20 -25
  240. data/src/core/lib/transport/transport_op_string.c +7 -19
  241. data/src/core/lib/tsi/fake_transport_security.c +2 -4
  242. data/src/core/lib/tsi/ssl_transport_security.c +7 -16
  243. data/src/core/lib/tsi/transport_security.c +2 -4
  244. data/src/ruby/ext/grpc/extconf.rb +4 -1
  245. data/src/ruby/ext/grpc/rb_byte_buffer.c +7 -0
  246. data/src/ruby/ext/grpc/rb_byte_buffer.h +3 -0
  247. data/src/ruby/ext/grpc/rb_call.c +47 -46
  248. data/src/ruby/ext/grpc/rb_channel.c +21 -6
  249. data/src/ruby/ext/grpc/rb_compression_options.c +9 -6
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -2
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +59 -8
  252. data/src/ruby/ext/grpc/rb_server.c +6 -4
  253. data/src/ruby/lib/grpc/generic/client_stub.rb +1 -1
  254. data/src/ruby/lib/grpc/version.rb +1 -1
  255. metadata +33 -9
@@ -0,0 +1,56 @@
1
+ /*
2
+ *
3
+ * Copyright 2016, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #ifndef GRPC_CORE_LIB_TRANSPORT_ERROR_UTILS_H
35
+ #define GRPC_CORE_LIB_TRANSPORT_ERROR_UTILS_H
36
+
37
+ #include "src/core/lib/iomgr/error.h"
38
+ #include "src/core/lib/transport/http2_errors.h"
39
+
40
+ /// A utility function to get the status code and message to be returned
41
+ /// to the application. If not set in the top-level message, looks
42
+ /// through child errors until it finds the first one with these attributes.
43
+ /// All attributes are pulled from the same child error. If any of the
44
+ /// attributes (code, msg, http_status) are unneeded, they can be passed as
45
+ /// NULL.
46
+ void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
47
+ grpc_status_code *code, const char **msg,
48
+ grpc_http2_error_code *http_status);
49
+
50
+ /// A utility function to check whether there is a clear status code that
51
+ /// doesn't need to be guessed in \a error. This means that \a error or some
52
+ /// child has GRPC_ERROR_INT_GRPC_STATUS set, or that it is GRPC_ERROR_NONE or
53
+ /// GRPC_ERROR_CANCELLED
54
+ bool grpc_error_has_clear_grpc_status(grpc_error *error);
55
+
56
+ #endif /* GRPC_CORE_LIB_TRANSPORT_ERROR_UTILS_H */
@@ -31,26 +31,26 @@
31
31
  *
32
32
  */
33
33
 
34
- #ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_ERRORS_H
35
- #define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_ERRORS_H
34
+ #ifndef GRPC_CORE_LIB_TRANSPORT_HTTP2_ERRORS_H
35
+ #define GRPC_CORE_LIB_TRANSPORT_HTTP2_ERRORS_H
36
36
 
37
37
  /* error codes for RST_STREAM from http2 draft 14 section 7 */
38
38
  typedef enum {
39
- GRPC_CHTTP2_NO_ERROR = 0x0,
40
- GRPC_CHTTP2_PROTOCOL_ERROR = 0x1,
41
- GRPC_CHTTP2_INTERNAL_ERROR = 0x2,
42
- GRPC_CHTTP2_FLOW_CONTROL_ERROR = 0x3,
43
- GRPC_CHTTP2_SETTINGS_TIMEOUT = 0x4,
44
- GRPC_CHTTP2_STREAM_CLOSED = 0x5,
45
- GRPC_CHTTP2_FRAME_SIZE_ERROR = 0x6,
46
- GRPC_CHTTP2_REFUSED_STREAM = 0x7,
47
- GRPC_CHTTP2_CANCEL = 0x8,
48
- GRPC_CHTTP2_COMPRESSION_ERROR = 0x9,
49
- GRPC_CHTTP2_CONNECT_ERROR = 0xa,
50
- GRPC_CHTTP2_ENHANCE_YOUR_CALM = 0xb,
51
- GRPC_CHTTP2_INADEQUATE_SECURITY = 0xc,
39
+ GRPC_HTTP2_NO_ERROR = 0x0,
40
+ GRPC_HTTP2_PROTOCOL_ERROR = 0x1,
41
+ GRPC_HTTP2_INTERNAL_ERROR = 0x2,
42
+ GRPC_HTTP2_FLOW_CONTROL_ERROR = 0x3,
43
+ GRPC_HTTP2_SETTINGS_TIMEOUT = 0x4,
44
+ GRPC_HTTP2_STREAM_CLOSED = 0x5,
45
+ GRPC_HTTP2_FRAME_SIZE_ERROR = 0x6,
46
+ GRPC_HTTP2_REFUSED_STREAM = 0x7,
47
+ GRPC_HTTP2_CANCEL = 0x8,
48
+ GRPC_HTTP2_COMPRESSION_ERROR = 0x9,
49
+ GRPC_HTTP2_CONNECT_ERROR = 0xa,
50
+ GRPC_HTTP2_ENHANCE_YOUR_CALM = 0xb,
51
+ GRPC_HTTP2_INADEQUATE_SECURITY = 0xc,
52
52
  /* force use of a default clause */
53
- GRPC_CHTTP2__ERROR_DO_NOT_USE = -1
54
- } grpc_chttp2_error_code;
53
+ GRPC_HTTP2__ERROR_DO_NOT_USE = -1
54
+ } grpc_http2_error_code;
55
55
 
56
- #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_ERRORS_H */
56
+ #endif /* GRPC_CORE_LIB_TRANSPORT_HTTP2_ERRORS_H */
@@ -48,12 +48,11 @@
48
48
  #include "src/core/lib/iomgr/iomgr_internal.h"
49
49
  #include "src/core/lib/profiling/timers.h"
50
50
  #include "src/core/lib/slice/slice_internal.h"
51
+ #include "src/core/lib/slice/slice_string_helpers.h"
51
52
  #include "src/core/lib/support/murmur_hash.h"
52
53
  #include "src/core/lib/support/string.h"
53
54
  #include "src/core/lib/transport/static_metadata.h"
54
55
 
55
- grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input);
56
-
57
56
  /* There are two kinds of mdelem and mdstr instances.
58
57
  * Static instances are declared in static_metadata.{h,c} and
59
58
  * are initialized by grpc_mdctx_global_init().
@@ -63,9 +62,6 @@ grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input);
63
62
  * used to determine which kind of element a pointer refers to.
64
63
  */
65
64
 
66
- #define INITIAL_STRTAB_CAPACITY 4
67
- #define INITIAL_MDTAB_CAPACITY 4
68
-
69
65
  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
70
66
  #define DEBUG_ARGS , const char *file, int line
71
67
  #define FWD_DEBUG_ARGS , file, line
@@ -76,37 +72,20 @@ grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input);
76
72
  #define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s))
77
73
  #endif
78
74
 
79
- #define TABLE_IDX(hash, log2_shards, capacity) \
80
- (((hash) >> (log2_shards)) % (capacity))
81
- #define SHARD_IDX(hash, log2_shards) ((hash) & ((1 << (log2_shards)) - 1))
82
-
83
- typedef void (*destroy_user_data_func)(void *user_data);
84
-
85
- #define SIZE_IN_DECODER_TABLE_NOT_SET -1
86
- /* Shadow structure for grpc_mdstr for non-static values */
87
- typedef struct internal_string {
88
- /* must be byte compatible with grpc_mdstr */
89
- grpc_slice slice;
90
- uint32_t hash;
91
-
92
- /* private only data */
93
- gpr_atm refcnt;
94
-
95
- uint8_t has_base64_and_huffman_encoded;
96
- grpc_slice_refcount refcount;
75
+ #define INITIAL_SHARD_CAPACITY 8
76
+ #define LOG2_SHARD_COUNT 4
77
+ #define SHARD_COUNT ((size_t)(1 << LOG2_SHARD_COUNT))
97
78
 
98
- grpc_slice base64_and_huffman;
79
+ #define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity))
80
+ #define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1))
99
81
 
100
- gpr_atm size_in_decoder_table;
101
-
102
- struct internal_string *bucket_next;
103
- } internal_string;
82
+ typedef void (*destroy_user_data_func)(void *user_data);
104
83
 
105
- /* Shadow structure for grpc_mdelem for non-static elements */
106
- typedef struct internal_metadata {
107
- /* must be byte compatible with grpc_mdelem */
108
- internal_string *key;
109
- internal_string *value;
84
+ /* Shadow structure for grpc_mdelem_data for interned elements */
85
+ typedef struct interned_metadata {
86
+ /* must be byte compatible with grpc_mdelem_data */
87
+ grpc_slice key;
88
+ grpc_slice value;
110
89
 
111
90
  /* private only data */
112
91
  gpr_atm refcnt;
@@ -115,19 +94,22 @@ typedef struct internal_metadata {
115
94
  gpr_atm destroy_user_data;
116
95
  gpr_atm user_data;
117
96
 
118
- struct internal_metadata *bucket_next;
119
- } internal_metadata;
97
+ struct interned_metadata *bucket_next;
98
+ } interned_metadata;
120
99
 
121
- typedef struct strtab_shard {
122
- gpr_mu mu;
123
- internal_string **strs;
124
- size_t count;
125
- size_t capacity;
126
- } strtab_shard;
100
+ /* Shadow structure for grpc_mdelem_data for allocated elements */
101
+ typedef struct allocated_metadata {
102
+ /* must be byte compatible with grpc_mdelem_data */
103
+ grpc_slice key;
104
+ grpc_slice value;
105
+
106
+ /* private only data */
107
+ gpr_atm refcnt;
108
+ } allocated_metadata;
127
109
 
128
110
  typedef struct mdtab_shard {
129
111
  gpr_mu mu;
130
- internal_metadata **elems;
112
+ interned_metadata **elems;
131
113
  size_t count;
132
114
  size_t capacity;
133
115
  /** Estimate of the number of unreferenced mdelems in the hash table.
@@ -136,102 +118,25 @@ typedef struct mdtab_shard {
136
118
  gpr_atm free_estimate;
137
119
  } mdtab_shard;
138
120
 
139
- #define LOG2_STRTAB_SHARD_COUNT 5
140
- #define LOG2_MDTAB_SHARD_COUNT 4
141
- #define STRTAB_SHARD_COUNT ((size_t)(1 << LOG2_STRTAB_SHARD_COUNT))
142
- #define MDTAB_SHARD_COUNT ((size_t)(1 << LOG2_MDTAB_SHARD_COUNT))
143
-
144
- /* hash seed: decided at initialization time */
145
- static uint32_t g_hash_seed;
146
- static int g_forced_hash_seed = 0;
147
-
148
- /* linearly probed hash tables for static element lookup */
149
- static grpc_mdstr *g_static_strtab[GRPC_STATIC_MDSTR_COUNT * 2];
150
- static grpc_mdelem *g_static_mdtab[GRPC_STATIC_MDELEM_COUNT * 2];
151
- static size_t g_static_strtab_maxprobe;
152
- static size_t g_static_mdtab_maxprobe;
153
-
154
- static strtab_shard g_strtab_shard[STRTAB_SHARD_COUNT];
155
- static mdtab_shard g_mdtab_shard[MDTAB_SHARD_COUNT];
121
+ static mdtab_shard g_shards[SHARD_COUNT];
156
122
 
157
123
  static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard);
158
124
 
159
- void grpc_test_only_set_metadata_hash_seed(uint32_t seed) {
160
- g_hash_seed = seed;
161
- g_forced_hash_seed = 1;
162
- }
163
-
164
125
  void grpc_mdctx_global_init(void) {
165
- size_t i, j;
166
- if (!g_forced_hash_seed) {
167
- g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec;
168
- }
169
- g_static_strtab_maxprobe = 0;
170
- g_static_mdtab_maxprobe = 0;
171
- /* build static tables */
172
- memset(g_static_mdtab, 0, sizeof(g_static_mdtab));
173
- memset(g_static_strtab, 0, sizeof(g_static_strtab));
174
- for (i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
175
- grpc_mdstr *elem = &grpc_static_mdstr_table[i];
176
- const char *str = grpc_static_metadata_strings[i];
177
- uint32_t hash = gpr_murmur_hash3(str, strlen(str), g_hash_seed);
178
- *(grpc_slice *)&elem->slice = grpc_slice_from_static_string(str);
179
- *(uint32_t *)&elem->hash = hash;
180
- for (j = 0;; j++) {
181
- size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_strtab);
182
- if (g_static_strtab[idx] == NULL) {
183
- g_static_strtab[idx] = &grpc_static_mdstr_table[i];
184
- break;
185
- }
186
- }
187
- if (j > g_static_strtab_maxprobe) {
188
- g_static_strtab_maxprobe = j;
189
- }
190
- }
191
- for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) {
192
- grpc_mdelem *elem = &grpc_static_mdelem_table[i];
193
- grpc_mdstr *key =
194
- &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 0]];
195
- grpc_mdstr *value =
196
- &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 1]];
197
- uint32_t hash = GRPC_MDSTR_KV_HASH(key->hash, value->hash);
198
- *(grpc_mdstr **)&elem->key = key;
199
- *(grpc_mdstr **)&elem->value = value;
200
- for (j = 0;; j++) {
201
- size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_mdtab);
202
- if (g_static_mdtab[idx] == NULL) {
203
- g_static_mdtab[idx] = elem;
204
- break;
205
- }
206
- }
207
- if (j > g_static_mdtab_maxprobe) {
208
- g_static_mdtab_maxprobe = j;
209
- }
210
- }
211
126
  /* initialize shards */
212
- for (i = 0; i < STRTAB_SHARD_COUNT; i++) {
213
- strtab_shard *shard = &g_strtab_shard[i];
214
- gpr_mu_init(&shard->mu);
215
- shard->count = 0;
216
- shard->capacity = INITIAL_STRTAB_CAPACITY;
217
- shard->strs = gpr_malloc(sizeof(*shard->strs) * shard->capacity);
218
- memset(shard->strs, 0, sizeof(*shard->strs) * shard->capacity);
219
- }
220
- for (i = 0; i < MDTAB_SHARD_COUNT; i++) {
221
- mdtab_shard *shard = &g_mdtab_shard[i];
127
+ for (size_t i = 0; i < SHARD_COUNT; i++) {
128
+ mdtab_shard *shard = &g_shards[i];
222
129
  gpr_mu_init(&shard->mu);
223
130
  shard->count = 0;
224
131
  gpr_atm_no_barrier_store(&shard->free_estimate, 0);
225
- shard->capacity = INITIAL_MDTAB_CAPACITY;
226
- shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity);
227
- memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity);
132
+ shard->capacity = INITIAL_SHARD_CAPACITY;
133
+ shard->elems = gpr_zalloc(sizeof(*shard->elems) * shard->capacity);
228
134
  }
229
135
  }
230
136
 
231
137
  void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) {
232
- size_t i;
233
- for (i = 0; i < MDTAB_SHARD_COUNT; i++) {
234
- mdtab_shard *shard = &g_mdtab_shard[i];
138
+ for (size_t i = 0; i < SHARD_COUNT; i++) {
139
+ mdtab_shard *shard = &g_shards[i];
235
140
  gpr_mu_destroy(&shard->mu);
236
141
  gc_mdtab(exec_ctx, shard);
237
142
  /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
@@ -244,212 +149,35 @@ void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) {
244
149
  }
245
150
  gpr_free(shard->elems);
246
151
  }
247
- for (i = 0; i < STRTAB_SHARD_COUNT; i++) {
248
- strtab_shard *shard = &g_strtab_shard[i];
249
- gpr_mu_destroy(&shard->mu);
250
- /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
251
- if (shard->count != 0) {
252
- gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked",
253
- shard->count);
254
- for (size_t j = 0; j < shard->capacity; j++) {
255
- for (internal_string *s = shard->strs[j]; s; s = s->bucket_next) {
256
- gpr_log(GPR_DEBUG, "LEAKED: %s",
257
- grpc_mdstr_as_c_string((grpc_mdstr *)s));
258
- }
259
- }
260
- if (grpc_iomgr_abort_on_leaks()) {
261
- abort();
262
- }
263
- }
264
- gpr_free(shard->strs);
265
- }
266
152
  }
267
153
 
268
- static int is_mdstr_static(grpc_mdstr *s) {
269
- return s >= &grpc_static_mdstr_table[0] &&
270
- s < &grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
271
- }
272
-
273
- static int is_mdelem_static(grpc_mdelem *e) {
274
- return e >= &grpc_static_mdelem_table[0] &&
275
- e < &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
154
+ static int is_mdelem_static(grpc_mdelem e) {
155
+ return GRPC_MDELEM_DATA(e) >= &grpc_static_mdelem_table[0] &&
156
+ GRPC_MDELEM_DATA(e) <
157
+ &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
276
158
  }
277
159
 
278
160
  static void ref_md_locked(mdtab_shard *shard,
279
- internal_metadata *md DEBUG_ARGS) {
161
+ interned_metadata *md DEBUG_ARGS) {
280
162
  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
163
+ char *key_str = grpc_slice_to_c_string(md->key);
164
+ char *value_str = grpc_slice_to_c_string(md->value);
281
165
  gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
282
166
  "ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
283
167
  gpr_atm_no_barrier_load(&md->refcnt),
284
- gpr_atm_no_barrier_load(&md->refcnt) + 1,
285
- grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
286
- grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
168
+ gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str);
169
+ gpr_free(key_str);
170
+ gpr_free(value_str);
287
171
  #endif
288
172
  if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) {
289
173
  gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1);
290
174
  }
291
175
  }
292
176
 
293
- static void grow_strtab(strtab_shard *shard) {
294
- size_t capacity = shard->capacity * 2;
295
- size_t i;
296
- internal_string **strtab;
297
- internal_string *s, *next;
298
-
299
- GPR_TIMER_BEGIN("grow_strtab", 0);
300
-
301
- strtab = gpr_malloc(sizeof(internal_string *) * capacity);
302
- memset(strtab, 0, sizeof(internal_string *) * capacity);
303
-
304
- for (i = 0; i < shard->capacity; i++) {
305
- for (s = shard->strs[i]; s; s = next) {
306
- size_t idx = TABLE_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT, capacity);
307
- next = s->bucket_next;
308
- s->bucket_next = strtab[idx];
309
- strtab[idx] = s;
310
- }
311
- }
312
-
313
- gpr_free(shard->strs);
314
- shard->strs = strtab;
315
- shard->capacity = capacity;
316
-
317
- GPR_TIMER_END("grow_strtab", 0);
318
- }
319
-
320
- static void internal_destroy_string(grpc_exec_ctx *exec_ctx,
321
- strtab_shard *shard, internal_string *is) {
322
- internal_string **prev_next;
323
- internal_string *cur;
324
- GPR_TIMER_BEGIN("internal_destroy_string", 0);
325
- if (is->has_base64_and_huffman_encoded) {
326
- grpc_slice_unref_internal(exec_ctx, is->base64_and_huffman);
327
- }
328
- for (prev_next = &shard->strs[TABLE_IDX(is->hash, LOG2_STRTAB_SHARD_COUNT,
329
- shard->capacity)],
330
- cur = *prev_next;
331
- cur != is; prev_next = &cur->bucket_next, cur = cur->bucket_next)
332
- ;
333
- *prev_next = cur->bucket_next;
334
- shard->count--;
335
- gpr_free(is);
336
- GPR_TIMER_END("internal_destroy_string", 0);
337
- }
338
-
339
- static void slice_ref(void *p) {
340
- internal_string *is =
341
- (internal_string *)((char *)p - offsetof(internal_string, refcount));
342
- GRPC_MDSTR_REF((grpc_mdstr *)(is));
343
- }
344
-
345
- static void slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
346
- internal_string *is =
347
- (internal_string *)((char *)p - offsetof(internal_string, refcount));
348
- GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)(is));
349
- }
350
-
351
- grpc_mdstr *grpc_mdstr_from_string(const char *str) {
352
- return grpc_mdstr_from_buffer((const uint8_t *)str, strlen(str));
353
- }
354
-
355
- grpc_mdstr *grpc_mdstr_from_slice(grpc_exec_ctx *exec_ctx, grpc_slice slice) {
356
- grpc_mdstr *result = grpc_mdstr_from_buffer(GRPC_SLICE_START_PTR(slice),
357
- GRPC_SLICE_LENGTH(slice));
358
- grpc_slice_unref_internal(exec_ctx, slice);
359
- return result;
360
- }
361
-
362
- grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) {
363
- uint32_t hash = gpr_murmur_hash3(buf, length, g_hash_seed);
364
- internal_string *s;
365
- strtab_shard *shard =
366
- &g_strtab_shard[SHARD_IDX(hash, LOG2_STRTAB_SHARD_COUNT)];
367
- size_t i;
368
- size_t idx;
369
-
370
- GPR_TIMER_BEGIN("grpc_mdstr_from_buffer", 0);
371
-
372
- /* search for a static string */
373
- for (i = 0; i <= g_static_strtab_maxprobe; i++) {
374
- grpc_mdstr *ss;
375
- idx = (hash + i) % GPR_ARRAY_SIZE(g_static_strtab);
376
- ss = g_static_strtab[idx];
377
- if (ss == NULL) break;
378
- if (ss->hash == hash && GRPC_SLICE_LENGTH(ss->slice) == length &&
379
- (length == 0 ||
380
- 0 == memcmp(buf, GRPC_SLICE_START_PTR(ss->slice), length))) {
381
- GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
382
- return ss;
383
- }
384
- }
385
-
386
- gpr_mu_lock(&shard->mu);
387
-
388
- /* search for an existing string */
389
- idx = TABLE_IDX(hash, LOG2_STRTAB_SHARD_COUNT, shard->capacity);
390
- for (s = shard->strs[idx]; s; s = s->bucket_next) {
391
- if (s->hash == hash && GRPC_SLICE_LENGTH(s->slice) == length &&
392
- 0 == memcmp(buf, GRPC_SLICE_START_PTR(s->slice), length)) {
393
- if (gpr_atm_full_fetch_add(&s->refcnt, 1) == 0) {
394
- /* If we get here, we've added a ref to something that was about to
395
- * die - drop it immediately.
396
- * The *only* possible path here (given the shard mutex) should be to
397
- * drop from one ref back to zero - assert that with a CAS */
398
- GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0));
399
- /* and treat this as if we were never here... sshhh */
400
- } else {
401
- gpr_mu_unlock(&shard->mu);
402
- GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
403
- return (grpc_mdstr *)s;
404
- }
405
- }
406
- }
407
-
408
- /* not found: create a new string */
409
- if (length + 1 < GRPC_SLICE_INLINED_SIZE) {
410
- /* string data goes directly into the slice */
411
- s = gpr_malloc(sizeof(internal_string));
412
- gpr_atm_rel_store(&s->refcnt, 1);
413
- s->slice.refcount = NULL;
414
- memcpy(s->slice.data.inlined.bytes, buf, length);
415
- s->slice.data.inlined.bytes[length] = 0;
416
- s->slice.data.inlined.length = (uint8_t)length;
417
- } else {
418
- /* string data goes after the internal_string header, and we +1 for null
419
- terminator */
420
- s = gpr_malloc(sizeof(internal_string) + length + 1);
421
- gpr_atm_rel_store(&s->refcnt, 1);
422
- s->refcount.ref = slice_ref;
423
- s->refcount.unref = slice_unref;
424
- s->slice.refcount = &s->refcount;
425
- s->slice.data.refcounted.bytes = (uint8_t *)(s + 1);
426
- s->slice.data.refcounted.length = length;
427
- memcpy(s->slice.data.refcounted.bytes, buf, length);
428
- /* add a null terminator for cheap c string conversion when desired */
429
- s->slice.data.refcounted.bytes[length] = 0;
430
- }
431
- s->has_base64_and_huffman_encoded = 0;
432
- s->hash = hash;
433
- s->size_in_decoder_table = SIZE_IN_DECODER_TABLE_NOT_SET;
434
- s->bucket_next = shard->strs[idx];
435
- shard->strs[idx] = s;
436
-
437
- shard->count++;
438
-
439
- if (shard->count > shard->capacity * 2) {
440
- grow_strtab(shard);
441
- }
442
-
443
- gpr_mu_unlock(&shard->mu);
444
- GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
445
-
446
- return (grpc_mdstr *)s;
447
- }
448
-
449
177
  static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
450
178
  size_t i;
451
- internal_metadata **prev_next;
452
- internal_metadata *md, *next;
179
+ interned_metadata **prev_next;
180
+ interned_metadata *md, *next;
453
181
  gpr_atm num_freed = 0;
454
182
 
455
183
  GPR_TIMER_BEGIN("gc_mdtab", 0);
@@ -459,8 +187,8 @@ static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
459
187
  void *user_data = (void *)gpr_atm_no_barrier_load(&md->user_data);
460
188
  next = md->bucket_next;
461
189
  if (gpr_atm_acq_load(&md->refcnt) == 0) {
462
- GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)md->key);
463
- GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)md->value);
190
+ grpc_slice_unref_internal(exec_ctx, md->key);
191
+ grpc_slice_unref_internal(exec_ctx, md->value);
464
192
  if (md->user_data) {
465
193
  ((destroy_user_data_func)gpr_atm_no_barrier_load(
466
194
  &md->destroy_user_data))(user_data);
@@ -481,21 +209,21 @@ static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
481
209
  static void grow_mdtab(mdtab_shard *shard) {
482
210
  size_t capacity = shard->capacity * 2;
483
211
  size_t i;
484
- internal_metadata **mdtab;
485
- internal_metadata *md, *next;
212
+ interned_metadata **mdtab;
213
+ interned_metadata *md, *next;
486
214
  uint32_t hash;
487
215
 
488
216
  GPR_TIMER_BEGIN("grow_mdtab", 0);
489
217
 
490
- mdtab = gpr_malloc(sizeof(internal_metadata *) * capacity);
491
- memset(mdtab, 0, sizeof(internal_metadata *) * capacity);
218
+ mdtab = gpr_zalloc(sizeof(interned_metadata *) * capacity);
492
219
 
493
220
  for (i = 0; i < shard->capacity; i++) {
494
221
  for (md = shard->elems[i]; md; md = next) {
495
222
  size_t idx;
496
- hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash);
223
+ hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key),
224
+ grpc_slice_hash(md->value));
497
225
  next = md->bucket_next;
498
- idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, capacity);
226
+ idx = TABLE_IDX(hash, capacity);
499
227
  md->bucket_next = mdtab[idx];
500
228
  mdtab[idx] = md;
501
229
  }
@@ -517,62 +245,77 @@ static void rehash_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) {
517
245
  }
518
246
  }
519
247
 
520
- grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx,
521
- grpc_mdstr *mkey,
522
- grpc_mdstr *mvalue) {
523
- internal_string *key = (internal_string *)mkey;
524
- internal_string *value = (internal_string *)mvalue;
525
- uint32_t hash = GRPC_MDSTR_KV_HASH(mkey->hash, mvalue->hash);
526
- internal_metadata *md;
527
- mdtab_shard *shard = &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)];
528
- size_t i;
529
- size_t idx;
248
+ grpc_mdelem grpc_mdelem_create(
249
+ grpc_exec_ctx *exec_ctx, grpc_slice key, grpc_slice value,
250
+ grpc_mdelem_data *compatible_external_backing_store) {
251
+ if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) {
252
+ if (compatible_external_backing_store != NULL) {
253
+ return GRPC_MAKE_MDELEM(compatible_external_backing_store,
254
+ GRPC_MDELEM_STORAGE_EXTERNAL);
255
+ }
530
256
 
531
- GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0);
257
+ allocated_metadata *allocated = gpr_malloc(sizeof(*allocated));
258
+ allocated->key = grpc_slice_ref_internal(key);
259
+ allocated->value = grpc_slice_ref_internal(value);
260
+ gpr_atm_rel_store(&allocated->refcnt, 1);
261
+ #ifdef GRPC_METADATA_REFCOUNT_DEBUG
262
+ char *key_str = grpc_slice_to_c_string(allocated->key);
263
+ char *value_str = grpc_slice_to_c_string(allocated->value);
264
+ gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%zu: '%s' = '%s'", (void *)allocated,
265
+ gpr_atm_no_barrier_load(&allocated->refcnt), key_str, value_str);
266
+ gpr_free(key_str);
267
+ gpr_free(value_str);
268
+ #endif
269
+ return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED);
270
+ }
532
271
 
533
- if (is_mdstr_static(mkey) && is_mdstr_static(mvalue)) {
534
- for (i = 0; i <= g_static_mdtab_maxprobe; i++) {
535
- grpc_mdelem *smd;
536
- idx = (hash + i) % GPR_ARRAY_SIZE(g_static_mdtab);
537
- smd = g_static_mdtab[idx];
538
- if (smd == NULL) break;
539
- if (smd->key == mkey && smd->value == mvalue) {
540
- GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
541
- return smd;
542
- }
272
+ if (GRPC_IS_STATIC_METADATA_STRING(key) &&
273
+ GRPC_IS_STATIC_METADATA_STRING(value)) {
274
+ grpc_mdelem static_elem = grpc_static_mdelem_for_static_strings(
275
+ GRPC_STATIC_METADATA_INDEX(key), GRPC_STATIC_METADATA_INDEX(value));
276
+ if (!GRPC_MDISNULL(static_elem)) {
277
+ return static_elem;
543
278
  }
544
279
  }
545
280
 
281
+ uint32_t hash =
282
+ GRPC_MDSTR_KV_HASH(grpc_slice_hash(key), grpc_slice_hash(value));
283
+ interned_metadata *md;
284
+ mdtab_shard *shard = &g_shards[SHARD_IDX(hash)];
285
+ size_t idx;
286
+
287
+ GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0);
288
+
546
289
  gpr_mu_lock(&shard->mu);
547
290
 
548
- idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, shard->capacity);
291
+ idx = TABLE_IDX(hash, shard->capacity);
549
292
  /* search for an existing pair */
550
293
  for (md = shard->elems[idx]; md; md = md->bucket_next) {
551
- if (md->key == key && md->value == value) {
294
+ if (grpc_slice_eq(key, md->key) && grpc_slice_eq(value, md->value)) {
552
295
  REF_MD_LOCKED(shard, md);
553
- GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)key);
554
- GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)value);
555
296
  gpr_mu_unlock(&shard->mu);
556
297
  GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
557
- return (grpc_mdelem *)md;
298
+ return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
558
299
  }
559
300
  }
560
301
 
561
302
  /* not found: create a new pair */
562
- md = gpr_malloc(sizeof(internal_metadata));
303
+ md = gpr_malloc(sizeof(interned_metadata));
563
304
  gpr_atm_rel_store(&md->refcnt, 1);
564
- md->key = key;
565
- md->value = value;
305
+ md->key = grpc_slice_ref_internal(key);
306
+ md->value = grpc_slice_ref_internal(value);
566
307
  md->user_data = 0;
567
308
  md->destroy_user_data = 0;
568
309
  md->bucket_next = shard->elems[idx];
569
310
  shard->elems[idx] = md;
570
311
  gpr_mu_init(&md->mu_user_data);
571
312
  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
313
+ char *key_str = grpc_slice_to_c_string(md->key);
314
+ char *value_str = grpc_slice_to_c_string(md->value);
572
315
  gpr_log(GPR_DEBUG, "ELM NEW:%p:%zu: '%s' = '%s'", (void *)md,
573
- gpr_atm_no_barrier_load(&md->refcnt),
574
- grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
575
- grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
316
+ gpr_atm_no_barrier_load(&md->refcnt), key_str, value_str);
317
+ gpr_free(key_str);
318
+ gpr_free(value_str);
576
319
  #endif
577
320
  shard->count++;
578
321
 
@@ -584,29 +327,26 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx,
584
327
 
585
328
  GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0);
586
329
 
587
- return (grpc_mdelem *)md;
588
- }
589
-
590
- grpc_mdelem *grpc_mdelem_from_strings(grpc_exec_ctx *exec_ctx, const char *key,
591
- const char *value) {
592
- return grpc_mdelem_from_metadata_strings(
593
- exec_ctx, grpc_mdstr_from_string(key), grpc_mdstr_from_string(value));
330
+ return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED);
594
331
  }
595
332
 
596
- grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
597
- grpc_slice value) {
598
- return grpc_mdelem_from_metadata_strings(
599
- exec_ctx, grpc_mdstr_from_slice(exec_ctx, key),
600
- grpc_mdstr_from_slice(exec_ctx, value));
333
+ grpc_mdelem grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
334
+ grpc_slice value) {
335
+ grpc_mdelem out = grpc_mdelem_create(exec_ctx, key, value, NULL);
336
+ grpc_slice_unref_internal(exec_ctx, key);
337
+ grpc_slice_unref_internal(exec_ctx, value);
338
+ return out;
601
339
  }
602
340
 
603
- grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_exec_ctx *exec_ctx,
604
- const char *key,
605
- const uint8_t *value,
606
- size_t value_length) {
607
- return grpc_mdelem_from_metadata_strings(
608
- exec_ctx, grpc_mdstr_from_string(key),
609
- grpc_mdstr_from_buffer(value, value_length));
341
+ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_exec_ctx *exec_ctx,
342
+ grpc_metadata *metadata) {
343
+ bool changed = false;
344
+ grpc_slice key_slice =
345
+ grpc_slice_maybe_static_intern(metadata->key, &changed);
346
+ grpc_slice value_slice =
347
+ grpc_slice_maybe_static_intern(metadata->value, &changed);
348
+ return grpc_mdelem_create(exec_ctx, key_slice, value_slice,
349
+ changed ? NULL : (grpc_mdelem_data *)metadata);
610
350
  }
611
351
 
612
352
  static size_t get_base64_encoded_size(size_t raw_length) {
@@ -614,160 +354,176 @@ static size_t get_base64_encoded_size(size_t raw_length) {
614
354
  return raw_length / 3 * 4 + tail_xtra[raw_length % 3];
615
355
  }
616
356
 
617
- size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem) {
618
- size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(elem->key->slice);
619
- size_t value_len = GRPC_SLICE_LENGTH(elem->value->slice);
620
- if (is_mdstr_static(elem->value)) {
621
- if (grpc_is_binary_header(
622
- (const char *)GRPC_SLICE_START_PTR(elem->key->slice),
623
- GRPC_SLICE_LENGTH(elem->key->slice))) {
624
- return overhead_and_key + get_base64_encoded_size(value_len);
625
- } else {
626
- return overhead_and_key + value_len;
627
- }
357
+ size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem) {
358
+ size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
359
+ size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
360
+ if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
361
+ return overhead_and_key + get_base64_encoded_size(value_len);
628
362
  } else {
629
- internal_string *is = (internal_string *)elem->value;
630
- gpr_atm current_size = gpr_atm_acq_load(&is->size_in_decoder_table);
631
- if (current_size == SIZE_IN_DECODER_TABLE_NOT_SET) {
632
- if (grpc_is_binary_header(
633
- (const char *)GRPC_SLICE_START_PTR(elem->key->slice),
634
- GRPC_SLICE_LENGTH(elem->key->slice))) {
635
- current_size = (gpr_atm)get_base64_encoded_size(value_len);
636
- } else {
637
- current_size = (gpr_atm)value_len;
638
- }
639
- gpr_atm_rel_store(&is->size_in_decoder_table, current_size);
640
- }
641
- return overhead_and_key + (size_t)current_size;
363
+ return overhead_and_key + value_len;
642
364
  }
643
365
  }
644
366
 
645
- grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) {
646
- internal_metadata *md = (internal_metadata *)gmd;
647
- if (is_mdelem_static(gmd)) return gmd;
367
+ grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) {
368
+ switch (GRPC_MDELEM_STORAGE(gmd)) {
369
+ case GRPC_MDELEM_STORAGE_EXTERNAL:
370
+ case GRPC_MDELEM_STORAGE_STATIC:
371
+ break;
372
+ case GRPC_MDELEM_STORAGE_INTERNED: {
373
+ interned_metadata *md = (interned_metadata *)GRPC_MDELEM_DATA(gmd);
648
374
  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
649
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
650
- "ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
651
- gpr_atm_no_barrier_load(&md->refcnt),
652
- gpr_atm_no_barrier_load(&md->refcnt) + 1,
653
- grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
654
- grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
375
+ char *key_str = grpc_slice_to_c_string(md->key);
376
+ char *value_str = grpc_slice_to_c_string(md->value);
377
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
378
+ "ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
379
+ gpr_atm_no_barrier_load(&md->refcnt),
380
+ gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str);
381
+ gpr_free(key_str);
382
+ gpr_free(value_str);
655
383
  #endif
656
- /* we can assume the ref count is >= 1 as the application is calling
657
- this function - meaning that no adjustment to mdtab_free is necessary,
658
- simplifying the logic here to be just an atomic increment */
659
- /* use C assert to have this removed in opt builds */
660
- GPR_ASSERT(gpr_atm_no_barrier_load(&md->refcnt) >= 1);
661
- gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
662
- return gmd;
663
- }
664
-
665
- void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *gmd DEBUG_ARGS) {
666
- internal_metadata *md = (internal_metadata *)gmd;
667
- if (!md) return;
668
- if (is_mdelem_static(gmd)) return;
384
+ /* we can assume the ref count is >= 1 as the application is calling
385
+ this function - meaning that no adjustment to mdtab_free is necessary,
386
+ simplifying the logic here to be just an atomic increment */
387
+ /* use C assert to have this removed in opt builds */
388
+ GPR_ASSERT(gpr_atm_no_barrier_load(&md->refcnt) >= 1);
389
+ gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
390
+ break;
391
+ }
392
+ case GRPC_MDELEM_STORAGE_ALLOCATED: {
393
+ allocated_metadata *md = (allocated_metadata *)GRPC_MDELEM_DATA(gmd);
669
394
  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
670
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
671
- "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
672
- gpr_atm_no_barrier_load(&md->refcnt),
673
- gpr_atm_no_barrier_load(&md->refcnt) - 1,
674
- grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
675
- grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
395
+ char *key_str = grpc_slice_to_c_string(md->key);
396
+ char *value_str = grpc_slice_to_c_string(md->value);
397
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
398
+ "ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
399
+ gpr_atm_no_barrier_load(&md->refcnt),
400
+ gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str);
401
+ gpr_free(key_str);
402
+ gpr_free(value_str);
676
403
  #endif
677
- uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash);
678
- const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
679
- GPR_ASSERT(prev_refcount >= 1);
680
- if (1 == prev_refcount) {
681
- /* once the refcount hits zero, some other thread can come along and
682
- free md at any time: it's unsafe from this point on to access it */
683
- mdtab_shard *shard =
684
- &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)];
685
- gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1);
404
+ /* we can assume the ref count is >= 1 as the application is calling
405
+ this function - meaning that no adjustment to mdtab_free is necessary,
406
+ simplifying the logic here to be just an atomic increment */
407
+ /* use C assert to have this removed in opt builds */
408
+ gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
409
+ break;
410
+ }
686
411
  }
412
+ return gmd;
687
413
  }
688
414
 
689
- const char *grpc_mdstr_as_c_string(const grpc_mdstr *s) {
690
- return (const char *)GRPC_SLICE_START_PTR(s->slice);
691
- }
692
-
693
- size_t grpc_mdstr_length(const grpc_mdstr *s) { return GRPC_MDSTR_LENGTH(s); }
694
-
695
- grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *gs DEBUG_ARGS) {
696
- internal_string *s = (internal_string *)gs;
697
- if (is_mdstr_static(gs)) return gs;
415
+ void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem gmd DEBUG_ARGS) {
416
+ switch (GRPC_MDELEM_STORAGE(gmd)) {
417
+ case GRPC_MDELEM_STORAGE_EXTERNAL:
418
+ case GRPC_MDELEM_STORAGE_STATIC:
419
+ break;
420
+ case GRPC_MDELEM_STORAGE_INTERNED: {
421
+ interned_metadata *md = (interned_metadata *)GRPC_MDELEM_DATA(gmd);
698
422
  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
699
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "STR REF:%p:%zu->%zu: '%s'",
700
- (void *)s, gpr_atm_no_barrier_load(&s->refcnt),
701
- gpr_atm_no_barrier_load(&s->refcnt) + 1, grpc_mdstr_as_c_string(gs));
423
+ char *key_str = grpc_slice_to_c_string(md->key);
424
+ char *value_str = grpc_slice_to_c_string(md->value);
425
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
426
+ "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
427
+ gpr_atm_no_barrier_load(&md->refcnt),
428
+ gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str);
429
+ gpr_free(key_str);
430
+ gpr_free(value_str);
702
431
  #endif
703
- GPR_ASSERT(gpr_atm_full_fetch_add(&s->refcnt, 1) > 0);
704
- return gs;
705
- }
706
-
707
- void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *gs DEBUG_ARGS) {
708
- internal_string *s = (internal_string *)gs;
709
- if (is_mdstr_static(gs)) return;
432
+ uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key),
433
+ grpc_slice_hash(md->value));
434
+ const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
435
+ GPR_ASSERT(prev_refcount >= 1);
436
+ if (1 == prev_refcount) {
437
+ /* once the refcount hits zero, some other thread can come along and
438
+ free md at any time: it's unsafe from this point on to access it */
439
+ mdtab_shard *shard = &g_shards[SHARD_IDX(hash)];
440
+ gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1);
441
+ }
442
+ break;
443
+ }
444
+ case GRPC_MDELEM_STORAGE_ALLOCATED: {
445
+ allocated_metadata *md = (allocated_metadata *)GRPC_MDELEM_DATA(gmd);
710
446
  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
711
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "STR UNREF:%p:%zu->%zu: '%s'",
712
- (void *)s, gpr_atm_no_barrier_load(&s->refcnt),
713
- gpr_atm_no_barrier_load(&s->refcnt) - 1, grpc_mdstr_as_c_string(gs));
447
+ char *key_str = grpc_slice_to_c_string(md->key);
448
+ char *value_str = grpc_slice_to_c_string(md->value);
449
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
450
+ "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
451
+ gpr_atm_no_barrier_load(&md->refcnt),
452
+ gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str);
453
+ gpr_free(key_str);
454
+ gpr_free(value_str);
714
455
  #endif
715
- if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) {
716
- strtab_shard *shard =
717
- &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)];
718
- gpr_mu_lock(&shard->mu);
719
- GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt));
720
- internal_destroy_string(exec_ctx, shard, s);
721
- gpr_mu_unlock(&shard->mu);
456
+ const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
457
+ GPR_ASSERT(prev_refcount >= 1);
458
+ if (1 == prev_refcount) {
459
+ grpc_slice_unref_internal(exec_ctx, md->key);
460
+ grpc_slice_unref_internal(exec_ctx, md->value);
461
+ gpr_free(md);
462
+ }
463
+ break;
464
+ }
722
465
  }
723
466
  }
724
467
 
725
- void *grpc_mdelem_get_user_data(grpc_mdelem *md, void (*destroy_func)(void *)) {
726
- internal_metadata *im = (internal_metadata *)md;
727
- void *result;
728
- if (is_mdelem_static(md)) {
729
- return (void *)grpc_static_mdelem_user_data[md - grpc_static_mdelem_table];
730
- }
731
- if (gpr_atm_acq_load(&im->destroy_user_data) == (gpr_atm)destroy_func) {
732
- return (void *)gpr_atm_no_barrier_load(&im->user_data);
733
- } else {
734
- return NULL;
468
+ void *grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void *)) {
469
+ switch (GRPC_MDELEM_STORAGE(md)) {
470
+ case GRPC_MDELEM_STORAGE_EXTERNAL:
471
+ case GRPC_MDELEM_STORAGE_ALLOCATED:
472
+ return NULL;
473
+ case GRPC_MDELEM_STORAGE_STATIC:
474
+ return (void *)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) -
475
+ grpc_static_mdelem_table];
476
+ case GRPC_MDELEM_STORAGE_INTERNED: {
477
+ interned_metadata *im = (interned_metadata *)GRPC_MDELEM_DATA(md);
478
+ void *result;
479
+ if (gpr_atm_acq_load(&im->destroy_user_data) == (gpr_atm)destroy_func) {
480
+ return (void *)gpr_atm_no_barrier_load(&im->user_data);
481
+ } else {
482
+ return NULL;
483
+ }
484
+ return result;
485
+ }
735
486
  }
736
- return result;
487
+ GPR_UNREACHABLE_CODE(return NULL);
737
488
  }
738
489
 
739
- void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
490
+ void *grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void *),
740
491
  void *user_data) {
741
- internal_metadata *im = (internal_metadata *)md;
742
- GPR_ASSERT(!is_mdelem_static(md));
743
- GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
744
- gpr_mu_lock(&im->mu_user_data);
745
- if (gpr_atm_no_barrier_load(&im->destroy_user_data)) {
746
- /* user data can only be set once */
747
- gpr_mu_unlock(&im->mu_user_data);
748
- if (destroy_func != NULL) {
492
+ switch (GRPC_MDELEM_STORAGE(md)) {
493
+ case GRPC_MDELEM_STORAGE_EXTERNAL:
494
+ case GRPC_MDELEM_STORAGE_ALLOCATED:
749
495
  destroy_func(user_data);
496
+ return NULL;
497
+ case GRPC_MDELEM_STORAGE_STATIC:
498
+ destroy_func(user_data);
499
+ return (void *)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) -
500
+ grpc_static_mdelem_table];
501
+ case GRPC_MDELEM_STORAGE_INTERNED: {
502
+ interned_metadata *im = (interned_metadata *)GRPC_MDELEM_DATA(md);
503
+ GPR_ASSERT(!is_mdelem_static(md));
504
+ GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
505
+ gpr_mu_lock(&im->mu_user_data);
506
+ if (gpr_atm_no_barrier_load(&im->destroy_user_data)) {
507
+ /* user data can only be set once */
508
+ gpr_mu_unlock(&im->mu_user_data);
509
+ if (destroy_func != NULL) {
510
+ destroy_func(user_data);
511
+ }
512
+ return (void *)gpr_atm_no_barrier_load(&im->user_data);
513
+ }
514
+ gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data);
515
+ gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func);
516
+ gpr_mu_unlock(&im->mu_user_data);
517
+ return user_data;
750
518
  }
751
- return (void *)gpr_atm_no_barrier_load(&im->user_data);
752
519
  }
753
- gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data);
754
- gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func);
755
- gpr_mu_unlock(&im->mu_user_data);
756
- return user_data;
520
+ GPR_UNREACHABLE_CODE(return NULL);
757
521
  }
758
522
 
759
- grpc_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) {
760
- internal_string *s = (internal_string *)gs;
761
- grpc_slice slice;
762
- strtab_shard *shard =
763
- &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)];
764
- gpr_mu_lock(&shard->mu);
765
- if (!s->has_base64_and_huffman_encoded) {
766
- s->base64_and_huffman =
767
- grpc_chttp2_base64_encode_and_huffman_compress(s->slice);
768
- s->has_base64_and_huffman_encoded = 1;
769
- }
770
- slice = s->base64_and_huffman;
771
- gpr_mu_unlock(&shard->mu);
772
- return slice;
523
+ bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b) {
524
+ if (a.payload == b.payload) return true;
525
+ if (GRPC_MDELEM_IS_INTERNED(a) && GRPC_MDELEM_IS_INTERNED(b)) return false;
526
+ if (GRPC_MDISNULL(a) || GRPC_MDISNULL(b)) return false;
527
+ return grpc_slice_eq(GRPC_MDKEY(a), GRPC_MDKEY(b)) &&
528
+ grpc_slice_eq(GRPC_MDVALUE(a), GRPC_MDVALUE(b));
773
529
  }