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
@@ -34,6 +34,7 @@
34
34
  #ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_H
35
35
  #define GRPC_CORE_LIB_TRANSPORT_METADATA_H
36
36
 
37
+ #include <grpc/grpc.h>
37
38
  #include <grpc/slice.h>
38
39
  #include <grpc/support/useful.h>
39
40
 
@@ -74,110 +75,110 @@ extern "C" {
74
75
  declared here - in which case those functions are effectively no-ops. */
75
76
 
76
77
  /* Forward declarations */
77
- typedef struct grpc_mdstr grpc_mdstr;
78
78
  typedef struct grpc_mdelem grpc_mdelem;
79
79
 
80
- /* if changing this, make identical changes in internal_string in metadata.c */
81
- struct grpc_mdstr {
82
- const grpc_slice slice;
83
- const uint32_t hash;
80
+ /* if changing this, make identical changes in:
81
+ - interned_metadata, allocated_metadata in metadata.c
82
+ - grpc_metadata in grpc_types.h */
83
+ typedef struct grpc_mdelem_data {
84
+ const grpc_slice key;
85
+ const grpc_slice value;
84
86
  /* there is a private part to this in metadata.c */
85
- };
87
+ } grpc_mdelem_data;
88
+
89
+ /* GRPC_MDELEM_STORAGE_* enum values that can be treated as interned always have
90
+ this bit set in their integer value */
91
+ #define GRPC_MDELEM_STORAGE_INTERNED_BIT 1
92
+
93
+ typedef enum {
94
+ /* memory pointed to by grpc_mdelem::payload is owned by an external system */
95
+ GRPC_MDELEM_STORAGE_EXTERNAL = 0,
96
+ /* memory pointed to by grpc_mdelem::payload is interned by the metadata
97
+ system */
98
+ GRPC_MDELEM_STORAGE_INTERNED = GRPC_MDELEM_STORAGE_INTERNED_BIT,
99
+ /* memory pointed to by grpc_mdelem::payload is allocated by the metadata
100
+ system */
101
+ GRPC_MDELEM_STORAGE_ALLOCATED = 2,
102
+ /* memory is in the static metadata table */
103
+ GRPC_MDELEM_STORAGE_STATIC = 2 | GRPC_MDELEM_STORAGE_INTERNED_BIT,
104
+ } grpc_mdelem_data_storage;
86
105
 
87
- /* if changing this, make identical changes in internal_metadata in
88
- metadata.c */
89
106
  struct grpc_mdelem {
90
- grpc_mdstr *const key;
91
- grpc_mdstr *const value;
92
- /* there is a private part to this in metadata.c */
107
+ /* a grpc_mdelem_data* generally, with the two lower bits signalling memory
108
+ ownership as per grpc_mdelem_data_storage */
109
+ uintptr_t payload;
93
110
  };
94
111
 
95
- void grpc_test_only_set_metadata_hash_seed(uint32_t seed);
96
-
97
- /* Constructors for grpc_mdstr instances; take a variety of data types that
98
- clients may have handy */
99
- grpc_mdstr *grpc_mdstr_from_string(const char *str);
100
- /* Unrefs the slice. */
101
- grpc_mdstr *grpc_mdstr_from_slice(grpc_exec_ctx *exec_ctx, grpc_slice slice);
102
- grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *str, size_t length);
103
-
104
- /* Returns a borrowed slice from the mdstr with its contents base64 encoded
105
- and huffman compressed */
106
- grpc_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *str);
107
-
108
- /* Constructors for grpc_mdelem instances; take a variety of data types that
109
- clients may have handy */
110
- grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx,
111
- grpc_mdstr *key,
112
- grpc_mdstr *value);
113
- grpc_mdelem *grpc_mdelem_from_strings(grpc_exec_ctx *exec_ctx, const char *key,
114
- const char *value);
112
+ #define GRPC_MDELEM_DATA(md) \
113
+ ((grpc_mdelem_data *)((md).payload & ~(uintptr_t)3))
114
+ #define GRPC_MDELEM_STORAGE(md) \
115
+ ((grpc_mdelem_data_storage)((md).payload & (uintptr_t)3))
116
+ #define GRPC_MAKE_MDELEM(data, storage) \
117
+ ((grpc_mdelem){((uintptr_t)(data)) | ((uintptr_t)storage)})
118
+ #define GRPC_MDELEM_IS_INTERNED(md) \
119
+ ((grpc_mdelem_data_storage)((md).payload & \
120
+ (uintptr_t)GRPC_MDELEM_STORAGE_INTERNED_BIT))
121
+
115
122
  /* Unrefs the slices. */
116
- grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
117
- grpc_slice value);
118
- grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_exec_ctx *exec_ctx,
119
- const char *key,
120
- const uint8_t *value,
121
- size_t value_length);
123
+ grpc_mdelem grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
124
+ grpc_slice value);
125
+
126
+ /* Cheaply convert a grpc_metadata to a grpc_mdelem; may use the grpc_metadata
127
+ object as backing storage (so lifetimes should align) */
128
+ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_exec_ctx *exec_ctx,
129
+ grpc_metadata *metadata);
122
130
 
123
- size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem);
131
+ /* Does not unref the slices; if a new non-interned mdelem is needed, allocates
132
+ one if compatible_external_backing_store is NULL, or uses
133
+ compatible_external_backing_store if it is non-NULL (in which case it's the
134
+ users responsibility to ensure that it outlives usage) */
135
+ grpc_mdelem grpc_mdelem_create(
136
+ grpc_exec_ctx *exec_ctx, grpc_slice key, grpc_slice value,
137
+ grpc_mdelem_data *compatible_external_backing_store);
138
+
139
+ bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);
140
+
141
+ size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem);
124
142
 
125
143
  /* Mutator and accessor for grpc_mdelem user data. The destructor function
126
144
  is used as a type tag and is checked during user_data fetch. */
127
- void *grpc_mdelem_get_user_data(grpc_mdelem *md,
145
+ void *grpc_mdelem_get_user_data(grpc_mdelem md,
128
146
  void (*if_destroy_func)(void *));
129
- void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
147
+ void *grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void *),
130
148
  void *user_data);
131
149
 
132
150
  /* Reference counting */
133
151
  //#define GRPC_METADATA_REFCOUNT_DEBUG
134
152
  #ifdef GRPC_METADATA_REFCOUNT_DEBUG
135
- #define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s), __FILE__, __LINE__)
136
- #define GRPC_MDSTR_UNREF(exec_ctx, s) \
137
- grpc_mdstr_unref((exec_ctx), (s), __FILE__, __LINE__)
138
153
  #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__)
139
154
  #define GRPC_MDELEM_UNREF(exec_ctx, s) \
140
155
  grpc_mdelem_unref((exec_ctx), (s), __FILE__, __LINE__)
141
- grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s, const char *file, int line);
142
- void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *s, const char *file,
143
- int line);
144
- grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md, const char *file, int line);
145
- void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *md,
156
+ grpc_mdelem grpc_mdelem_ref(grpc_mdelem md, const char *file, int line);
157
+ void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem md,
146
158
  const char *file, int line);
147
159
  #else
148
- #define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s))
149
- #define GRPC_MDSTR_UNREF(exec_ctx, s) grpc_mdstr_unref((exec_ctx), (s))
150
160
  #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s))
151
161
  #define GRPC_MDELEM_UNREF(exec_ctx, s) grpc_mdelem_unref((exec_ctx), (s))
152
- grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s);
153
- void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *s);
154
- grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md);
155
- void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *md);
162
+ grpc_mdelem grpc_mdelem_ref(grpc_mdelem md);
163
+ void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem md);
156
164
  #endif
157
165
 
158
- /* Recover a char* from a grpc_mdstr. The returned string is null terminated.
159
- Does not promise that the returned string has no embedded nulls however. */
160
- const char *grpc_mdstr_as_c_string(const grpc_mdstr *s);
166
+ #define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key)
167
+ #define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value)
161
168
 
162
- #define GRPC_MDSTR_LENGTH(s) (GRPC_SLICE_LENGTH(s->slice))
169
+ #define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL)
170
+ #define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL)
163
171
 
164
172
  /* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */
165
- #define GRPC_MDELEM_LENGTH(e) \
166
- (GRPC_MDSTR_LENGTH((e)->key) + GRPC_MDSTR_LENGTH((e)->value) + 32)
167
-
168
- int grpc_mdstr_is_legal_header(grpc_mdstr *s);
169
- int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s);
170
- int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s);
173
+ #define GRPC_MDELEM_LENGTH(e) \
174
+ (GRPC_SLICE_LENGTH(GRPC_MDKEY((e))) + GRPC_SLICE_LENGTH(GRPC_MDVALUE((e))) + \
175
+ 32)
171
176
 
172
177
  #define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
173
178
 
174
179
  void grpc_mdctx_global_init(void);
175
180
  void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx);
176
181
 
177
- /* Implementation provided by chttp2_transport */
178
- extern grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(
179
- grpc_slice input);
180
-
181
182
  #ifdef __cplusplus
182
183
  }
183
184
  #endif
@@ -40,6 +40,8 @@
40
40
  #include <grpc/support/log.h>
41
41
 
42
42
  #include "src/core/lib/profiling/timers.h"
43
+ #include "src/core/lib/slice/slice_internal.h"
44
+ #include "src/core/lib/slice/slice_string_helpers.h"
43
45
 
44
46
  static void assert_valid_list(grpc_mdelem_list *list) {
45
47
  #ifndef NDEBUG
@@ -51,16 +53,34 @@ static void assert_valid_list(grpc_mdelem_list *list) {
51
53
  GPR_ASSERT(list->tail->next == NULL);
52
54
  GPR_ASSERT((list->head == list->tail) == (list->head->next == NULL));
53
55
 
56
+ size_t verified_count = 0;
54
57
  for (l = list->head; l; l = l->next) {
55
- GPR_ASSERT(l->md);
58
+ GPR_ASSERT(!GRPC_MDISNULL(l->md));
56
59
  GPR_ASSERT((l->prev == NULL) == (l == list->head));
57
60
  GPR_ASSERT((l->next == NULL) == (l == list->tail));
58
61
  if (l->next) GPR_ASSERT(l->next->prev == l);
59
62
  if (l->prev) GPR_ASSERT(l->prev->next == l);
63
+ verified_count++;
60
64
  }
65
+ GPR_ASSERT(list->count == verified_count);
61
66
  #endif /* NDEBUG */
62
67
  }
63
68
 
69
+ static void assert_valid_callouts(grpc_exec_ctx *exec_ctx,
70
+ grpc_metadata_batch *batch) {
71
+ #ifndef NDEBUG
72
+ for (grpc_linked_mdelem *l = batch->list.head; l != NULL; l = l->next) {
73
+ grpc_slice key_interned = grpc_slice_intern(GRPC_MDKEY(l->md));
74
+ grpc_metadata_batch_callouts_index callout_idx =
75
+ GRPC_BATCH_INDEX_OF(key_interned);
76
+ if (callout_idx != GRPC_BATCH_CALLOUTS_COUNT) {
77
+ GPR_ASSERT(batch->idx.array[callout_idx] == l);
78
+ }
79
+ grpc_slice_unref_internal(exec_ctx, key_interned);
80
+ }
81
+ #endif
82
+ }
83
+
64
84
  #ifndef NDEBUG
65
85
  void grpc_metadata_batch_assert_ok(grpc_metadata_batch *batch) {
66
86
  assert_valid_list(&batch->list);
@@ -68,7 +88,7 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch *batch) {
68
88
  #endif /* NDEBUG */
69
89
 
70
90
  void grpc_metadata_batch_init(grpc_metadata_batch *batch) {
71
- batch->list.head = batch->list.tail = NULL;
91
+ memset(batch, 0, sizeof(*batch));
72
92
  batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
73
93
  }
74
94
 
@@ -80,17 +100,58 @@ void grpc_metadata_batch_destroy(grpc_exec_ctx *exec_ctx,
80
100
  }
81
101
  }
82
102
 
83
- void grpc_metadata_batch_add_head(grpc_metadata_batch *batch,
84
- grpc_linked_mdelem *storage,
85
- grpc_mdelem *elem_to_add) {
86
- GPR_ASSERT(elem_to_add);
103
+ grpc_error *grpc_attach_md_to_error(grpc_error *src, grpc_mdelem md) {
104
+ char *k = grpc_slice_to_c_string(GRPC_MDKEY(md));
105
+ char *v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
106
+ grpc_error *out = grpc_error_set_str(
107
+ grpc_error_set_str(src, GRPC_ERROR_STR_KEY, k), GRPC_ERROR_STR_VALUE, v);
108
+ gpr_free(k);
109
+ gpr_free(v);
110
+ return out;
111
+ }
112
+
113
+ static grpc_error *maybe_link_callout(grpc_metadata_batch *batch,
114
+ grpc_linked_mdelem *storage)
115
+ GRPC_MUST_USE_RESULT;
116
+
117
+ static grpc_error *maybe_link_callout(grpc_metadata_batch *batch,
118
+ grpc_linked_mdelem *storage) {
119
+ grpc_metadata_batch_callouts_index idx =
120
+ GRPC_BATCH_INDEX_OF(GRPC_MDKEY(storage->md));
121
+ if (idx == GRPC_BATCH_CALLOUTS_COUNT) {
122
+ return GRPC_ERROR_NONE;
123
+ }
124
+ if (batch->idx.array[idx] == NULL) {
125
+ batch->idx.array[idx] = storage;
126
+ return GRPC_ERROR_NONE;
127
+ }
128
+ return grpc_attach_md_to_error(
129
+ GRPC_ERROR_CREATE("Unallowed duplicate metadata"), storage->md);
130
+ }
131
+
132
+ static void maybe_unlink_callout(grpc_metadata_batch *batch,
133
+ grpc_linked_mdelem *storage) {
134
+ grpc_metadata_batch_callouts_index idx =
135
+ GRPC_BATCH_INDEX_OF(GRPC_MDKEY(storage->md));
136
+ if (idx == GRPC_BATCH_CALLOUTS_COUNT) {
137
+ return;
138
+ }
139
+ GPR_ASSERT(batch->idx.array[idx] != NULL);
140
+ batch->idx.array[idx] = NULL;
141
+ }
142
+
143
+ grpc_error *grpc_metadata_batch_add_head(grpc_exec_ctx *exec_ctx,
144
+ grpc_metadata_batch *batch,
145
+ grpc_linked_mdelem *storage,
146
+ grpc_mdelem elem_to_add) {
147
+ GPR_ASSERT(!GRPC_MDISNULL(elem_to_add));
87
148
  storage->md = elem_to_add;
88
- grpc_metadata_batch_link_head(batch, storage);
149
+ return grpc_metadata_batch_link_head(exec_ctx, batch, storage);
89
150
  }
90
151
 
91
152
  static void link_head(grpc_mdelem_list *list, grpc_linked_mdelem *storage) {
92
153
  assert_valid_list(list);
93
- GPR_ASSERT(storage->md);
154
+ GPR_ASSERT(!GRPC_MDISNULL(storage->md));
94
155
  storage->prev = NULL;
95
156
  storage->next = list->head;
96
157
  if (list->head != NULL) {
@@ -99,25 +160,36 @@ static void link_head(grpc_mdelem_list *list, grpc_linked_mdelem *storage) {
99
160
  list->tail = storage;
100
161
  }
101
162
  list->head = storage;
163
+ list->count++;
102
164
  assert_valid_list(list);
103
165
  }
104
166
 
105
- void grpc_metadata_batch_link_head(grpc_metadata_batch *batch,
106
- grpc_linked_mdelem *storage) {
167
+ grpc_error *grpc_metadata_batch_link_head(grpc_exec_ctx *exec_ctx,
168
+ grpc_metadata_batch *batch,
169
+ grpc_linked_mdelem *storage) {
170
+ assert_valid_callouts(exec_ctx, batch);
171
+ grpc_error *err = maybe_link_callout(batch, storage);
172
+ if (err != GRPC_ERROR_NONE) {
173
+ assert_valid_callouts(exec_ctx, batch);
174
+ return err;
175
+ }
107
176
  link_head(&batch->list, storage);
177
+ assert_valid_callouts(exec_ctx, batch);
178
+ return GRPC_ERROR_NONE;
108
179
  }
109
180
 
110
- void grpc_metadata_batch_add_tail(grpc_metadata_batch *batch,
111
- grpc_linked_mdelem *storage,
112
- grpc_mdelem *elem_to_add) {
113
- GPR_ASSERT(elem_to_add);
181
+ grpc_error *grpc_metadata_batch_add_tail(grpc_exec_ctx *exec_ctx,
182
+ grpc_metadata_batch *batch,
183
+ grpc_linked_mdelem *storage,
184
+ grpc_mdelem elem_to_add) {
185
+ GPR_ASSERT(!GRPC_MDISNULL(elem_to_add));
114
186
  storage->md = elem_to_add;
115
- grpc_metadata_batch_link_tail(batch, storage);
187
+ return grpc_metadata_batch_link_tail(exec_ctx, batch, storage);
116
188
  }
117
189
 
118
190
  static void link_tail(grpc_mdelem_list *list, grpc_linked_mdelem *storage) {
119
191
  assert_valid_list(list);
120
- GPR_ASSERT(storage->md);
192
+ GPR_ASSERT(!GRPC_MDISNULL(storage->md));
121
193
  storage->prev = list->tail;
122
194
  storage->next = NULL;
123
195
  storage->reserved = NULL;
@@ -127,70 +199,88 @@ static void link_tail(grpc_mdelem_list *list, grpc_linked_mdelem *storage) {
127
199
  list->head = storage;
128
200
  }
129
201
  list->tail = storage;
202
+ list->count++;
130
203
  assert_valid_list(list);
131
204
  }
132
205
 
133
- void grpc_metadata_batch_link_tail(grpc_metadata_batch *batch,
134
- grpc_linked_mdelem *storage) {
206
+ grpc_error *grpc_metadata_batch_link_tail(grpc_exec_ctx *exec_ctx,
207
+ grpc_metadata_batch *batch,
208
+ grpc_linked_mdelem *storage) {
209
+ assert_valid_callouts(exec_ctx, batch);
210
+ grpc_error *err = maybe_link_callout(batch, storage);
211
+ if (err != GRPC_ERROR_NONE) {
212
+ assert_valid_callouts(exec_ctx, batch);
213
+ return err;
214
+ }
135
215
  link_tail(&batch->list, storage);
216
+ assert_valid_callouts(exec_ctx, batch);
217
+ return GRPC_ERROR_NONE;
136
218
  }
137
219
 
138
- void grpc_metadata_batch_move(grpc_metadata_batch *dst,
139
- grpc_metadata_batch *src) {
140
- *dst = *src;
141
- memset(src, 0, sizeof(grpc_metadata_batch));
220
+ static void unlink_storage(grpc_mdelem_list *list,
221
+ grpc_linked_mdelem *storage) {
222
+ assert_valid_list(list);
223
+ if (storage->prev != NULL) {
224
+ storage->prev->next = storage->next;
225
+ } else {
226
+ list->head = storage->next;
227
+ }
228
+ if (storage->next != NULL) {
229
+ storage->next->prev = storage->prev;
230
+ } else {
231
+ list->tail = storage->prev;
232
+ }
233
+ list->count--;
234
+ assert_valid_list(list);
142
235
  }
143
236
 
144
- void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
237
+ void grpc_metadata_batch_remove(grpc_exec_ctx *exec_ctx,
145
238
  grpc_metadata_batch *batch,
146
- grpc_mdelem *(*filter)(grpc_exec_ctx *exec_ctx,
147
- void *user_data,
148
- grpc_mdelem *elem),
149
- void *user_data) {
150
- grpc_linked_mdelem *l;
151
- grpc_linked_mdelem *next;
239
+ grpc_linked_mdelem *storage) {
240
+ assert_valid_callouts(exec_ctx, batch);
241
+ maybe_unlink_callout(batch, storage);
242
+ unlink_storage(&batch->list, storage);
243
+ GRPC_MDELEM_UNREF(exec_ctx, storage->md);
244
+ assert_valid_callouts(exec_ctx, batch);
245
+ }
152
246
 
153
- GPR_TIMER_BEGIN("grpc_metadata_batch_filter", 0);
247
+ void grpc_metadata_batch_set_value(grpc_exec_ctx *exec_ctx,
248
+ grpc_linked_mdelem *storage,
249
+ grpc_slice value) {
250
+ grpc_mdelem old = storage->md;
251
+ grpc_mdelem new = grpc_mdelem_from_slices(
252
+ exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(old)), value);
253
+ storage->md = new;
254
+ GRPC_MDELEM_UNREF(exec_ctx, old);
255
+ }
154
256
 
155
- assert_valid_list(&batch->list);
156
- for (l = batch->list.head; l; l = next) {
157
- grpc_mdelem *orig = l->md;
158
- grpc_mdelem *filt = filter(exec_ctx, user_data, orig);
159
- next = l->next;
160
- if (filt == NULL) {
161
- if (l->prev) {
162
- l->prev->next = l->next;
163
- }
164
- if (l->next) {
165
- l->next->prev = l->prev;
166
- }
167
- if (batch->list.head == l) {
168
- batch->list.head = l->next;
169
- }
170
- if (batch->list.tail == l) {
171
- batch->list.tail = l->prev;
172
- }
173
- assert_valid_list(&batch->list);
174
- GRPC_MDELEM_UNREF(exec_ctx, l->md);
175
- } else if (filt != orig) {
176
- GRPC_MDELEM_UNREF(exec_ctx, orig);
177
- l->md = filt;
257
+ grpc_error *grpc_metadata_batch_substitute(grpc_exec_ctx *exec_ctx,
258
+ grpc_metadata_batch *batch,
259
+ grpc_linked_mdelem *storage,
260
+ grpc_mdelem new) {
261
+ assert_valid_callouts(exec_ctx, batch);
262
+ grpc_error *error = GRPC_ERROR_NONE;
263
+ grpc_mdelem old = storage->md;
264
+ if (!grpc_slice_eq(GRPC_MDKEY(new), GRPC_MDKEY(old))) {
265
+ maybe_unlink_callout(batch, storage);
266
+ storage->md = new;
267
+ error = maybe_link_callout(batch, storage);
268
+ if (error != GRPC_ERROR_NONE) {
269
+ unlink_storage(&batch->list, storage);
270
+ GRPC_MDELEM_UNREF(exec_ctx, storage->md);
178
271
  }
272
+ } else {
273
+ storage->md = new;
179
274
  }
180
- assert_valid_list(&batch->list);
181
-
182
- GPR_TIMER_END("grpc_metadata_batch_filter", 0);
183
- }
184
-
185
- static grpc_mdelem *no_metadata_for_you(grpc_exec_ctx *exec_ctx,
186
- void *user_data, grpc_mdelem *elem) {
187
- return NULL;
275
+ GRPC_MDELEM_UNREF(exec_ctx, old);
276
+ assert_valid_callouts(exec_ctx, batch);
277
+ return error;
188
278
  }
189
279
 
190
280
  void grpc_metadata_batch_clear(grpc_exec_ctx *exec_ctx,
191
281
  grpc_metadata_batch *batch) {
192
- batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
193
- grpc_metadata_batch_filter(exec_ctx, batch, no_metadata_for_you, NULL);
282
+ grpc_metadata_batch_destroy(exec_ctx, batch);
283
+ grpc_metadata_batch_init(batch);
194
284
  }
195
285
 
196
286
  bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) {
@@ -207,3 +297,33 @@ size_t grpc_metadata_batch_size(grpc_metadata_batch *batch) {
207
297
  }
208
298
  return size;
209
299
  }
300
+
301
+ static void add_error(grpc_error **composite, grpc_error *error,
302
+ const char *composite_error_string) {
303
+ if (error == GRPC_ERROR_NONE) return;
304
+ if (*composite == GRPC_ERROR_NONE) {
305
+ *composite = GRPC_ERROR_CREATE(composite_error_string);
306
+ }
307
+ *composite = grpc_error_add_child(*composite, error);
308
+ }
309
+
310
+ grpc_error *grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
311
+ grpc_metadata_batch *batch,
312
+ grpc_metadata_batch_filter_func func,
313
+ void *user_data,
314
+ const char *composite_error_string) {
315
+ grpc_linked_mdelem *l = batch->list.head;
316
+ grpc_error *error = GRPC_ERROR_NONE;
317
+ while (l) {
318
+ grpc_linked_mdelem *next = l->next;
319
+ grpc_filtered_mdelem new = func(exec_ctx, user_data, l->md);
320
+ add_error(&error, new.error, composite_error_string);
321
+ if (GRPC_MDISNULL(new.md)) {
322
+ grpc_metadata_batch_remove(exec_ctx, batch, l);
323
+ } else if (new.md.payload != l->md.payload) {
324
+ grpc_metadata_batch_substitute(exec_ctx, batch, l, new.md);
325
+ }
326
+ l = next;
327
+ }
328
+ return error;
329
+ }