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
@@ -29,7 +29,7 @@
29
29
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
  //
31
31
 
32
- #include "src/core/lib/transport/mdstr_hash_table.h"
32
+ #include "src/core/lib/slice/slice_hash_table.h"
33
33
 
34
34
  #include <stdbool.h>
35
35
  #include <string.h>
@@ -37,70 +37,77 @@
37
37
  #include <grpc/support/alloc.h>
38
38
  #include <grpc/support/log.h>
39
39
 
40
+ #include "src/core/lib/slice/slice_internal.h"
40
41
  #include "src/core/lib/transport/metadata.h"
41
42
 
42
- struct grpc_mdstr_hash_table {
43
+ struct grpc_slice_hash_table {
43
44
  gpr_refcount refs;
44
45
  size_t size;
45
- grpc_mdstr_hash_table_entry* entries;
46
+ grpc_slice_hash_table_entry* entries;
46
47
  };
47
48
 
49
+ static bool is_empty(grpc_slice_hash_table_entry* entry) {
50
+ return entry->vtable == NULL;
51
+ }
52
+
48
53
  // Helper function for insert and get operations that performs quadratic
49
54
  // probing (https://en.wikipedia.org/wiki/Quadratic_probing).
50
- static size_t grpc_mdstr_hash_table_find_index(
51
- const grpc_mdstr_hash_table* table, const grpc_mdstr* key,
52
- bool find_empty) {
55
+ static size_t grpc_slice_hash_table_find_index(
56
+ const grpc_slice_hash_table* table, const grpc_slice key, bool find_empty) {
57
+ size_t hash = grpc_slice_hash(key);
53
58
  for (size_t i = 0; i < table->size; ++i) {
54
- const size_t idx = (key->hash + i * i) % table->size;
55
- if (table->entries[idx].key == NULL) return find_empty ? idx : table->size;
56
- if (table->entries[idx].key == key) return idx;
59
+ const size_t idx = (hash + i * i) % table->size;
60
+ if (is_empty(&table->entries[idx])) {
61
+ return find_empty ? idx : table->size;
62
+ }
63
+ if (grpc_slice_eq(table->entries[idx].key, key)) {
64
+ return idx;
65
+ }
57
66
  }
58
67
  return table->size; // Not found.
59
68
  }
60
69
 
61
- static void grpc_mdstr_hash_table_add(
62
- grpc_mdstr_hash_table* table, grpc_mdstr* key, void* value,
63
- const grpc_mdstr_hash_table_vtable* vtable) {
70
+ static void grpc_slice_hash_table_add(
71
+ grpc_slice_hash_table* table, grpc_slice key, void* value,
72
+ const grpc_slice_hash_table_vtable* vtable) {
64
73
  GPR_ASSERT(value != NULL);
65
74
  const size_t idx =
66
- grpc_mdstr_hash_table_find_index(table, key, true /* find_empty */);
75
+ grpc_slice_hash_table_find_index(table, key, true /* find_empty */);
67
76
  GPR_ASSERT(idx != table->size); // Table should never be full.
68
- grpc_mdstr_hash_table_entry* entry = &table->entries[idx];
69
- entry->key = GRPC_MDSTR_REF(key);
77
+ grpc_slice_hash_table_entry* entry = &table->entries[idx];
78
+ entry->key = grpc_slice_ref_internal(key);
70
79
  entry->value = vtable->copy_value(value);
71
80
  entry->vtable = vtable;
72
81
  }
73
82
 
74
- grpc_mdstr_hash_table* grpc_mdstr_hash_table_create(
75
- size_t num_entries, grpc_mdstr_hash_table_entry* entries) {
76
- grpc_mdstr_hash_table* table = gpr_malloc(sizeof(*table));
77
- memset(table, 0, sizeof(*table));
83
+ grpc_slice_hash_table* grpc_slice_hash_table_create(
84
+ size_t num_entries, grpc_slice_hash_table_entry* entries) {
85
+ grpc_slice_hash_table* table = gpr_zalloc(sizeof(*table));
78
86
  gpr_ref_init(&table->refs, 1);
79
87
  // Quadratic probing gets best performance when the table is no more
80
88
  // than half full.
81
89
  table->size = num_entries * 2;
82
- const size_t entry_size = sizeof(grpc_mdstr_hash_table_entry) * table->size;
83
- table->entries = gpr_malloc(entry_size);
84
- memset(table->entries, 0, entry_size);
90
+ const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size;
91
+ table->entries = gpr_zalloc(entry_size);
85
92
  for (size_t i = 0; i < num_entries; ++i) {
86
- grpc_mdstr_hash_table_entry* entry = &entries[i];
87
- grpc_mdstr_hash_table_add(table, entry->key, entry->value, entry->vtable);
93
+ grpc_slice_hash_table_entry* entry = &entries[i];
94
+ grpc_slice_hash_table_add(table, entry->key, entry->value, entry->vtable);
88
95
  }
89
96
  return table;
90
97
  }
91
98
 
92
- grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table) {
99
+ grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table) {
93
100
  if (table != NULL) gpr_ref(&table->refs);
94
101
  return table;
95
102
  }
96
103
 
97
- void grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx,
98
- grpc_mdstr_hash_table* table) {
104
+ void grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx,
105
+ grpc_slice_hash_table* table) {
99
106
  if (table != NULL && gpr_unref(&table->refs)) {
100
107
  for (size_t i = 0; i < table->size; ++i) {
101
- grpc_mdstr_hash_table_entry* entry = &table->entries[i];
102
- if (entry->key != NULL) {
103
- GRPC_MDSTR_UNREF(exec_ctx, entry->key);
108
+ grpc_slice_hash_table_entry* entry = &table->entries[i];
109
+ if (!is_empty(entry)) {
110
+ grpc_slice_unref_internal(exec_ctx, entry->key);
104
111
  entry->vtable->destroy_value(exec_ctx, entry->value);
105
112
  }
106
113
  }
@@ -109,10 +116,10 @@ void grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx,
109
116
  }
110
117
  }
111
118
 
112
- void* grpc_mdstr_hash_table_get(const grpc_mdstr_hash_table* table,
113
- const grpc_mdstr* key) {
119
+ void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
120
+ const grpc_slice key) {
114
121
  const size_t idx =
115
- grpc_mdstr_hash_table_find_index(table, key, false /* find_empty */);
122
+ grpc_slice_hash_table_find_index(table, key, false /* find_empty */);
116
123
  if (idx == table->size) return NULL; // Not found.
117
124
  return table->entries[idx].value;
118
125
  }
@@ -29,8 +29,8 @@
29
29
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
  */
31
31
 
32
- #ifndef GRPC_CORE_LIB_TRANSPORT_MDSTR_HASH_TABLE_H
33
- #define GRPC_CORE_LIB_TRANSPORT_MDSTR_HASH_TABLE_H
32
+ #ifndef GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H
33
+ #define GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H
34
34
 
35
35
  #include "src/core/lib/transport/metadata.h"
36
36
 
@@ -40,38 +40,38 @@
40
40
  * (https://en.wikipedia.org/wiki/Open_addressing) with quadratic
41
41
  * probing (https://en.wikipedia.org/wiki/Quadratic_probing).
42
42
  *
43
- * The keys are \a grpc_mdstr objects. The values are arbitrary pointers
43
+ * The keys are \a grpc_slice objects. The values are arbitrary pointers
44
44
  * with a common vtable.
45
45
  *
46
46
  * Hash tables are intentionally immutable, to avoid the need for locking.
47
47
  */
48
48
 
49
- typedef struct grpc_mdstr_hash_table grpc_mdstr_hash_table;
49
+ typedef struct grpc_slice_hash_table grpc_slice_hash_table;
50
50
 
51
- typedef struct grpc_mdstr_hash_table_vtable {
52
- void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value);
53
- void* (*copy_value)(void* value);
54
- } grpc_mdstr_hash_table_vtable;
51
+ typedef struct grpc_slice_hash_table_vtable {
52
+ void (*destroy_value)(grpc_exec_ctx *exec_ctx, void *value);
53
+ void *(*copy_value)(void *value);
54
+ } grpc_slice_hash_table_vtable;
55
55
 
56
- typedef struct grpc_mdstr_hash_table_entry {
57
- grpc_mdstr* key;
58
- void* value; /* Must not be NULL. */
59
- const grpc_mdstr_hash_table_vtable* vtable;
60
- } grpc_mdstr_hash_table_entry;
56
+ typedef struct grpc_slice_hash_table_entry {
57
+ grpc_slice key;
58
+ void *value; /* Must not be NULL. */
59
+ const grpc_slice_hash_table_vtable *vtable;
60
+ } grpc_slice_hash_table_entry;
61
61
 
62
62
  /** Creates a new hash table of containing \a entries, which is an array
63
63
  of length \a num_entries.
64
64
  Creates its own copy of all keys and values from \a entries. */
65
- grpc_mdstr_hash_table* grpc_mdstr_hash_table_create(
66
- size_t num_entries, grpc_mdstr_hash_table_entry* entries);
65
+ grpc_slice_hash_table *grpc_slice_hash_table_create(
66
+ size_t num_entries, grpc_slice_hash_table_entry *entries);
67
67
 
68
- grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table);
69
- void grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx,
70
- grpc_mdstr_hash_table* table);
68
+ grpc_slice_hash_table *grpc_slice_hash_table_ref(grpc_slice_hash_table *table);
69
+ void grpc_slice_hash_table_unref(grpc_exec_ctx *exec_ctx,
70
+ grpc_slice_hash_table *table);
71
71
 
72
72
  /** Returns the value from \a table associated with \a key.
73
73
  Returns NULL if \a key is not found. */
74
- void* grpc_mdstr_hash_table_get(const grpc_mdstr_hash_table* table,
75
- const grpc_mdstr* key);
74
+ void *grpc_slice_hash_table_get(const grpc_slice_hash_table *table,
75
+ const grpc_slice key);
76
76
 
77
- #endif /* GRPC_CORE_LIB_TRANSPORT_MDSTR_HASH_TABLE_H */
77
+ #endif /* GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H */
@@ -0,0 +1,346 @@
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
+ #include "src/core/lib/slice/slice_internal.h"
35
+
36
+ #include <string.h>
37
+
38
+ #include <grpc/support/alloc.h>
39
+ #include <grpc/support/log.h>
40
+
41
+ #include "src/core/lib/iomgr/iomgr_internal.h" /* for iomgr_abort_on_leaks() */
42
+ #include "src/core/lib/profiling/timers.h"
43
+ #include "src/core/lib/slice/slice_string_helpers.h"
44
+ #include "src/core/lib/support/murmur_hash.h"
45
+ #include "src/core/lib/transport/static_metadata.h"
46
+
47
+ #define LOG2_SHARD_COUNT 5
48
+ #define SHARD_COUNT (1 << LOG2_SHARD_COUNT)
49
+ #define INITIAL_SHARD_CAPACITY 8
50
+
51
+ #define TABLE_IDX(hash, capacity) (((hash) >> LOG2_SHARD_COUNT) % (capacity))
52
+ #define SHARD_IDX(hash) ((hash) & ((1 << LOG2_SHARD_COUNT) - 1))
53
+
54
+ typedef struct interned_slice_refcount {
55
+ grpc_slice_refcount base;
56
+ grpc_slice_refcount sub;
57
+ size_t length;
58
+ gpr_atm refcnt;
59
+ uint32_t hash;
60
+ struct interned_slice_refcount *bucket_next;
61
+ } interned_slice_refcount;
62
+
63
+ typedef struct slice_shard {
64
+ gpr_mu mu;
65
+ interned_slice_refcount **strs;
66
+ size_t count;
67
+ size_t capacity;
68
+ } slice_shard;
69
+
70
+ /* hash seed: decided at initialization time */
71
+ static uint32_t g_hash_seed;
72
+ static int g_forced_hash_seed = 0;
73
+
74
+ static slice_shard g_shards[SHARD_COUNT];
75
+
76
+ typedef struct {
77
+ uint32_t hash;
78
+ uint32_t idx;
79
+ } static_metadata_hash_ent;
80
+
81
+ static static_metadata_hash_ent
82
+ static_metadata_hash[4 * GRPC_STATIC_MDSTR_COUNT];
83
+ static uint32_t max_static_metadata_hash_probe;
84
+ static uint32_t static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT];
85
+
86
+ static void interned_slice_ref(void *p) {
87
+ interned_slice_refcount *s = p;
88
+ GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) > 0);
89
+ }
90
+
91
+ static void interned_slice_destroy(interned_slice_refcount *s) {
92
+ slice_shard *shard = &g_shards[SHARD_IDX(s->hash)];
93
+ gpr_mu_lock(&shard->mu);
94
+ GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt));
95
+ interned_slice_refcount **prev_next;
96
+ interned_slice_refcount *cur;
97
+ for (prev_next = &shard->strs[TABLE_IDX(s->hash, shard->capacity)],
98
+ cur = *prev_next;
99
+ cur != s; prev_next = &cur->bucket_next, cur = cur->bucket_next)
100
+ ;
101
+ *prev_next = cur->bucket_next;
102
+ shard->count--;
103
+ gpr_free(s);
104
+ gpr_mu_unlock(&shard->mu);
105
+ }
106
+
107
+ static void interned_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
108
+ interned_slice_refcount *s = p;
109
+ if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) {
110
+ interned_slice_destroy(s);
111
+ }
112
+ }
113
+
114
+ static void interned_slice_sub_ref(void *p) {
115
+ interned_slice_ref(((char *)p) - offsetof(interned_slice_refcount, sub));
116
+ }
117
+
118
+ static void interned_slice_sub_unref(grpc_exec_ctx *exec_ctx, void *p) {
119
+ interned_slice_unref(exec_ctx,
120
+ ((char *)p) - offsetof(interned_slice_refcount, sub));
121
+ }
122
+
123
+ static uint32_t interned_slice_hash(grpc_slice slice) {
124
+ interned_slice_refcount *s = (interned_slice_refcount *)slice.refcount;
125
+ return s->hash;
126
+ }
127
+
128
+ static int interned_slice_eq(grpc_slice a, grpc_slice b) {
129
+ return a.refcount == b.refcount;
130
+ }
131
+
132
+ static const grpc_slice_refcount_vtable interned_slice_vtable = {
133
+ interned_slice_ref, interned_slice_unref, interned_slice_eq,
134
+ interned_slice_hash};
135
+ static const grpc_slice_refcount_vtable interned_slice_sub_vtable = {
136
+ interned_slice_sub_ref, interned_slice_sub_unref,
137
+ grpc_slice_default_eq_impl, grpc_slice_default_hash_impl};
138
+
139
+ static void grow_shard(slice_shard *shard) {
140
+ size_t capacity = shard->capacity * 2;
141
+ size_t i;
142
+ interned_slice_refcount **strtab;
143
+ interned_slice_refcount *s, *next;
144
+
145
+ GPR_TIMER_BEGIN("grow_strtab", 0);
146
+
147
+ strtab = gpr_zalloc(sizeof(interned_slice_refcount *) * capacity);
148
+
149
+ for (i = 0; i < shard->capacity; i++) {
150
+ for (s = shard->strs[i]; s; s = next) {
151
+ size_t idx = TABLE_IDX(s->hash, capacity);
152
+ next = s->bucket_next;
153
+ s->bucket_next = strtab[idx];
154
+ strtab[idx] = s;
155
+ }
156
+ }
157
+
158
+ gpr_free(shard->strs);
159
+ shard->strs = strtab;
160
+ shard->capacity = capacity;
161
+
162
+ GPR_TIMER_END("grow_strtab", 0);
163
+ }
164
+
165
+ static grpc_slice materialize(interned_slice_refcount *s) {
166
+ grpc_slice slice;
167
+ slice.refcount = &s->base;
168
+ slice.data.refcounted.bytes = (uint8_t *)(s + 1);
169
+ slice.data.refcounted.length = s->length;
170
+ return slice;
171
+ }
172
+
173
+ uint32_t grpc_slice_default_hash_impl(grpc_slice s) {
174
+ return gpr_murmur_hash3(GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s),
175
+ g_hash_seed);
176
+ }
177
+
178
+ uint32_t grpc_static_slice_hash(grpc_slice s) {
179
+ return static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX(s)];
180
+ }
181
+
182
+ int grpc_static_slice_eq(grpc_slice a, grpc_slice b) {
183
+ return GRPC_STATIC_METADATA_INDEX(a) == GRPC_STATIC_METADATA_INDEX(b);
184
+ }
185
+
186
+ uint32_t grpc_slice_hash(grpc_slice s) {
187
+ return s.refcount == NULL ? grpc_slice_default_hash_impl(s)
188
+ : s.refcount->vtable->hash(s);
189
+ }
190
+
191
+ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice,
192
+ bool *returned_slice_is_different) {
193
+ if (GRPC_IS_STATIC_METADATA_STRING(slice)) {
194
+ return slice;
195
+ }
196
+
197
+ uint32_t hash = grpc_slice_hash(slice);
198
+ for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
199
+ static_metadata_hash_ent ent =
200
+ static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
201
+ if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
202
+ grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) {
203
+ *returned_slice_is_different = true;
204
+ return grpc_static_slice_table[ent.idx];
205
+ }
206
+ }
207
+
208
+ return slice;
209
+ }
210
+
211
+ bool grpc_slice_is_interned(grpc_slice slice) {
212
+ return (slice.refcount && slice.refcount->vtable == &interned_slice_vtable) ||
213
+ GRPC_IS_STATIC_METADATA_STRING(slice);
214
+ }
215
+
216
+ grpc_slice grpc_slice_intern(grpc_slice slice) {
217
+ GPR_TIMER_BEGIN("grpc_slice_intern", 0);
218
+ if (GRPC_IS_STATIC_METADATA_STRING(slice)) {
219
+ GPR_TIMER_END("grpc_slice_intern", 0);
220
+ return slice;
221
+ }
222
+
223
+ uint32_t hash = grpc_slice_hash(slice);
224
+ for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
225
+ static_metadata_hash_ent ent =
226
+ static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
227
+ if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
228
+ grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) {
229
+ GPR_TIMER_END("grpc_slice_intern", 0);
230
+ return grpc_static_slice_table[ent.idx];
231
+ }
232
+ }
233
+
234
+ interned_slice_refcount *s;
235
+ slice_shard *shard = &g_shards[SHARD_IDX(hash)];
236
+
237
+ gpr_mu_lock(&shard->mu);
238
+
239
+ /* search for an existing string */
240
+ size_t idx = TABLE_IDX(hash, shard->capacity);
241
+ for (s = shard->strs[idx]; s; s = s->bucket_next) {
242
+ if (s->hash == hash && grpc_slice_eq(slice, materialize(s))) {
243
+ if (gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) == 0) {
244
+ /* If we get here, we've added a ref to something that was about to
245
+ * die - drop it immediately.
246
+ * The *only* possible path here (given the shard mutex) should be to
247
+ * drop from one ref back to zero - assert that with a CAS */
248
+ GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0));
249
+ /* and treat this as if we were never here... sshhh */
250
+ } else {
251
+ gpr_mu_unlock(&shard->mu);
252
+ GPR_TIMER_END("grpc_slice_intern", 0);
253
+ return materialize(s);
254
+ }
255
+ }
256
+ }
257
+
258
+ /* not found: create a new string */
259
+ /* string data goes after the internal_string header */
260
+ s = gpr_malloc(sizeof(*s) + GRPC_SLICE_LENGTH(slice));
261
+ gpr_atm_rel_store(&s->refcnt, 1);
262
+ s->length = GRPC_SLICE_LENGTH(slice);
263
+ s->hash = hash;
264
+ s->base.vtable = &interned_slice_vtable;
265
+ s->base.sub_refcount = &s->sub;
266
+ s->sub.vtable = &interned_slice_sub_vtable;
267
+ s->sub.sub_refcount = &s->sub;
268
+ s->bucket_next = shard->strs[idx];
269
+ shard->strs[idx] = s;
270
+ memcpy(s + 1, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice));
271
+
272
+ shard->count++;
273
+
274
+ if (shard->count > shard->capacity * 2) {
275
+ grow_shard(shard);
276
+ }
277
+
278
+ gpr_mu_unlock(&shard->mu);
279
+
280
+ GPR_TIMER_END("grpc_slice_intern", 0);
281
+ return materialize(s);
282
+ }
283
+
284
+ void grpc_test_only_set_slice_hash_seed(uint32_t seed) {
285
+ g_hash_seed = seed;
286
+ g_forced_hash_seed = 1;
287
+ }
288
+
289
+ void grpc_slice_intern_init(void) {
290
+ if (!g_forced_hash_seed) {
291
+ g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec;
292
+ }
293
+ for (size_t i = 0; i < SHARD_COUNT; i++) {
294
+ slice_shard *shard = &g_shards[i];
295
+ gpr_mu_init(&shard->mu);
296
+ shard->count = 0;
297
+ shard->capacity = INITIAL_SHARD_CAPACITY;
298
+ shard->strs = gpr_zalloc(sizeof(*shard->strs) * shard->capacity);
299
+ }
300
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(static_metadata_hash); i++) {
301
+ static_metadata_hash[i].hash = 0;
302
+ static_metadata_hash[i].idx = GRPC_STATIC_MDSTR_COUNT;
303
+ }
304
+ max_static_metadata_hash_probe = 0;
305
+ for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
306
+ static_metadata_hash_values[i] =
307
+ grpc_slice_default_hash_impl(grpc_static_slice_table[i]);
308
+ for (size_t j = 0; j < GPR_ARRAY_SIZE(static_metadata_hash); j++) {
309
+ size_t slot = (static_metadata_hash_values[i] + j) %
310
+ GPR_ARRAY_SIZE(static_metadata_hash);
311
+ if (static_metadata_hash[slot].idx == GRPC_STATIC_MDSTR_COUNT) {
312
+ static_metadata_hash[slot].hash = static_metadata_hash_values[i];
313
+ static_metadata_hash[slot].idx = (uint32_t)i;
314
+ if (j > max_static_metadata_hash_probe) {
315
+ max_static_metadata_hash_probe = (uint32_t)j;
316
+ }
317
+ break;
318
+ }
319
+ }
320
+ }
321
+ }
322
+
323
+ void grpc_slice_intern_shutdown(void) {
324
+ for (size_t i = 0; i < SHARD_COUNT; i++) {
325
+ slice_shard *shard = &g_shards[i];
326
+ gpr_mu_destroy(&shard->mu);
327
+ /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
328
+ if (shard->count != 0) {
329
+ gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked",
330
+ shard->count);
331
+ for (size_t j = 0; j < shard->capacity; j++) {
332
+ for (interned_slice_refcount *s = shard->strs[j]; s;
333
+ s = s->bucket_next) {
334
+ char *text =
335
+ grpc_dump_slice(materialize(s), GPR_DUMP_HEX | GPR_DUMP_ASCII);
336
+ gpr_log(GPR_DEBUG, "LEAKED: %s", text);
337
+ gpr_free(text);
338
+ }
339
+ }
340
+ if (grpc_iomgr_abort_on_leaks()) {
341
+ abort();
342
+ }
343
+ }
344
+ gpr_free(shard->strs);
345
+ }
346
+ }