grpc 1.2.5 → 1.3.4

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 (327) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1434 -399
  3. data/etc/roots.pem +34 -150
  4. data/include/grpc/grpc.h +71 -0
  5. data/include/grpc/impl/codegen/atm.h +5 -0
  6. data/include/grpc/impl/codegen/atm_gcc_atomic.h +6 -0
  7. data/include/grpc/impl/codegen/atm_gcc_sync.h +2 -0
  8. data/include/grpc/impl/codegen/atm_windows.h +11 -0
  9. data/include/grpc/impl/codegen/grpc_types.h +54 -13
  10. data/include/grpc/impl/codegen/port_platform.h +15 -1
  11. data/include/grpc/support/alloc.h +2 -1
  12. data/include/grpc/support/sync.h +4 -0
  13. data/include/grpc/support/tls.h +1 -1
  14. data/src/core/ext/census/gen/trace_context.pb.h +1 -1
  15. data/src/core/ext/census/grpc_filter.c +14 -10
  16. data/src/core/ext/census/grpc_plugin.c +3 -1
  17. data/src/core/ext/census/trace_label.h +1 -1
  18. data/src/core/ext/census/trace_propagation.h +1 -1
  19. data/src/core/ext/census/trace_status.h +1 -1
  20. data/src/core/ext/census/trace_string.h +1 -1
  21. data/src/core/ext/census/tracing.h +1 -1
  22. data/src/core/ext/{client_channel → filters/client_channel}/channel_connectivity.c +56 -27
  23. data/src/core/ext/{client_channel → filters/client_channel}/client_channel.c +407 -202
  24. data/src/core/ext/{client_channel → filters/client_channel}/client_channel.h +10 -6
  25. data/src/core/ext/{client_channel → filters/client_channel}/client_channel_factory.c +1 -1
  26. data/src/core/ext/{client_channel → filters/client_channel}/client_channel_factory.h +4 -4
  27. data/src/core/ext/{client_channel → filters/client_channel}/client_channel_plugin.c +12 -7
  28. data/src/core/ext/{client_channel → filters/client_channel}/connector.c +1 -1
  29. data/src/core/ext/{client_channel → filters/client_channel}/connector.h +3 -5
  30. data/src/core/ext/{client_channel → filters/client_channel}/http_connect_handshaker.c +6 -6
  31. data/src/core/ext/{client_channel → filters/client_channel}/http_connect_handshaker.h +3 -3
  32. data/src/core/ext/{client_channel → filters/client_channel}/http_proxy.c +4 -4
  33. data/src/core/ext/{client_channel → filters/client_channel}/http_proxy.h +3 -3
  34. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy.c +1 -1
  35. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy.h +4 -4
  36. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb.c +22 -20
  37. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb.h +4 -4
  38. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb_channel.h +5 -4
  39. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb_channel_secure.c +2 -2
  40. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/load_balancer_api.c +1 -1
  41. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/load_balancer_api.h +6 -5
  42. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +1 -1
  43. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +0 -0
  44. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/pick_first/pick_first.c +20 -15
  45. data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/round_robin/round_robin.c +21 -16
  46. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_factory.c +1 -1
  47. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_factory.h +5 -5
  48. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_registry.c +1 -1
  49. data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_registry.h +4 -4
  50. data/src/core/ext/{client_channel → filters/client_channel}/parse_address.c +1 -1
  51. data/src/core/ext/{client_channel → filters/client_channel}/parse_address.h +4 -4
  52. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper.c +1 -1
  53. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper.h +3 -3
  54. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper_registry.c +10 -4
  55. data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper_registry.h +4 -4
  56. data/src/core/ext/{client_channel → filters/client_channel}/resolver.c +1 -1
  57. data/src/core/ext/{client_channel → filters/client_channel}/resolver.h +4 -4
  58. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +350 -0
  59. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +66 -0
  60. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c +319 -0
  61. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +289 -0
  62. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +64 -0
  63. data/src/core/ext/{resolver → filters/client_channel/resolver}/dns/native/dns_resolver.c +21 -5
  64. data/src/core/ext/{resolver → filters/client_channel/resolver}/sockaddr/sockaddr_resolver.c +3 -3
  65. data/src/core/ext/{client_channel → filters/client_channel}/resolver_factory.c +1 -1
  66. data/src/core/ext/{client_channel → filters/client_channel}/resolver_factory.h +6 -6
  67. data/src/core/ext/{client_channel → filters/client_channel}/resolver_registry.c +1 -2
  68. data/src/core/ext/{client_channel → filters/client_channel}/resolver_registry.h +4 -4
  69. data/src/core/ext/filters/client_channel/retry_throttle.c +210 -0
  70. data/src/core/ext/filters/client_channel/retry_throttle.h +65 -0
  71. data/src/core/ext/{client_channel → filters/client_channel}/subchannel.c +49 -43
  72. data/src/core/ext/{client_channel → filters/client_channel}/subchannel.h +21 -7
  73. data/src/core/ext/{client_channel → filters/client_channel}/subchannel_index.c +1 -1
  74. data/src/core/ext/{client_channel → filters/client_channel}/subchannel_index.h +5 -5
  75. data/src/core/ext/{client_channel → filters/client_channel}/uri_parser.c +1 -1
  76. data/src/core/ext/{client_channel → filters/client_channel}/uri_parser.h +3 -3
  77. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting.c +4 -2
  78. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting.h +3 -3
  79. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting_filter.c +17 -14
  80. data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting_filter.h +4 -4
  81. data/src/core/ext/filters/max_age/max_age_filter.c +439 -0
  82. data/src/core/ext/filters/max_age/max_age_filter.h +39 -0
  83. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +6 -41
  84. data/src/core/ext/transport/chttp2/client/chttp2_connector.h +1 -1
  85. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +2 -2
  86. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +3 -3
  87. data/src/core/ext/transport/chttp2/server/chttp2_server.c +2 -2
  88. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +2 -5
  89. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +2 -2
  90. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +449 -204
  91. data/src/core/ext/transport/chttp2/transport/frame_data.c +10 -7
  92. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +3 -2
  93. data/src/core/ext/transport/chttp2/transport/frame_ping.c +37 -7
  94. data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -0
  95. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +4 -3
  96. data/src/core/ext/transport/chttp2/transport/frame_settings.c +18 -38
  97. data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -29
  98. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +2 -2
  99. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +64 -37
  100. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +11 -4
  101. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +60 -39
  102. data/src/core/ext/transport/chttp2/transport/hpack_table.c +2 -2
  103. data/src/core/ext/transport/chttp2/transport/http2_settings.c +75 -0
  104. data/src/core/ext/transport/chttp2/transport/http2_settings.h +74 -0
  105. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +22 -43
  106. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +8 -10
  107. data/src/core/ext/transport/chttp2/transport/internal.h +24 -2
  108. data/src/core/ext/transport/chttp2/transport/parsing.c +33 -15
  109. data/src/core/ext/transport/chttp2/transport/writing.c +56 -10
  110. data/src/core/lib/channel/channel_args.c +7 -0
  111. data/src/core/lib/channel/channel_args.h +2 -0
  112. data/src/core/lib/channel/channel_stack.c +20 -27
  113. data/src/core/lib/channel/channel_stack.h +18 -16
  114. data/src/core/lib/channel/compress_filter.c +20 -18
  115. data/src/core/lib/channel/connected_channel.c +9 -8
  116. data/src/core/lib/channel/deadline_filter.c +28 -24
  117. data/src/core/lib/channel/deadline_filter.h +3 -3
  118. data/src/core/lib/channel/handshaker.c +3 -2
  119. data/src/core/lib/channel/http_client_filter.c +119 -61
  120. data/src/core/lib/channel/http_server_filter.c +124 -69
  121. data/src/core/lib/channel/message_size_filter.c +23 -19
  122. data/src/core/lib/http/httpcli.c +8 -6
  123. data/src/core/lib/http/httpcli_security_connector.c +5 -5
  124. data/src/core/lib/http/parser.c +57 -31
  125. data/src/core/lib/iomgr/closure.c +15 -0
  126. data/src/core/lib/iomgr/closure.h +4 -0
  127. data/src/core/lib/iomgr/combiner.c +8 -0
  128. data/src/core/lib/iomgr/endpoint_pair.h +2 -3
  129. data/src/core/lib/iomgr/endpoint_pair_posix.c +10 -7
  130. data/src/core/lib/iomgr/endpoint_pair_uv.c +2 -3
  131. data/src/core/lib/iomgr/endpoint_pair_windows.c +9 -6
  132. data/src/core/lib/iomgr/error.c +360 -177
  133. data/src/core/lib/iomgr/error.h +31 -33
  134. data/src/core/lib/iomgr/error_internal.h +30 -9
  135. data/src/core/lib/iomgr/ev_epoll_linux.c +25 -239
  136. data/src/core/lib/iomgr/ev_poll_posix.c +11 -7
  137. data/src/core/lib/iomgr/ev_posix.c +6 -0
  138. data/src/core/lib/iomgr/ev_posix.h +3 -0
  139. data/src/core/lib/iomgr/exec_ctx.c +6 -0
  140. data/src/core/lib/iomgr/executor.c +8 -2
  141. data/src/core/lib/iomgr/load_file.c +6 -3
  142. data/src/core/lib/iomgr/lockfree_event.c +238 -0
  143. data/src/core/{ext/client_channel/initial_connect_string.h → lib/iomgr/lockfree_event.h} +17 -13
  144. data/src/core/lib/iomgr/pollset.h +4 -0
  145. data/src/core/lib/iomgr/pollset_windows.c +2 -2
  146. data/src/core/lib/iomgr/port.h +9 -0
  147. data/src/core/lib/iomgr/resolve_address_posix.c +15 -9
  148. data/src/core/lib/iomgr/resolve_address_uv.c +8 -6
  149. data/src/core/lib/iomgr/resolve_address_windows.c +2 -2
  150. data/src/core/lib/iomgr/resource_quota.c +19 -4
  151. data/src/core/lib/iomgr/resource_quota.h +2 -0
  152. data/src/core/lib/iomgr/sockaddr_utils.c +3 -1
  153. data/src/core/lib/iomgr/socket_factory_posix.c +110 -0
  154. data/src/core/lib/iomgr/socket_factory_posix.h +90 -0
  155. data/src/core/lib/iomgr/socket_utils_common_posix.c +25 -9
  156. data/src/core/lib/iomgr/socket_utils_posix.h +7 -0
  157. data/src/core/lib/iomgr/tcp_client.h +0 -4
  158. data/src/core/lib/iomgr/tcp_client_posix.c +15 -31
  159. data/src/core/lib/iomgr/tcp_client_uv.c +10 -6
  160. data/src/core/lib/iomgr/tcp_client_windows.c +9 -19
  161. data/src/core/lib/iomgr/tcp_posix.c +111 -22
  162. data/src/core/lib/iomgr/tcp_posix.h +3 -4
  163. data/src/core/lib/iomgr/tcp_server_posix.c +39 -417
  164. data/src/core/lib/iomgr/tcp_server_utils_posix.h +135 -0
  165. data/src/core/lib/iomgr/tcp_server_utils_posix_common.c +221 -0
  166. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c +196 -0
  167. data/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c +49 -0
  168. data/src/core/lib/iomgr/tcp_server_uv.c +43 -16
  169. data/src/core/lib/iomgr/tcp_server_windows.c +10 -22
  170. data/src/core/lib/iomgr/tcp_uv.c +16 -13
  171. data/src/core/lib/iomgr/tcp_windows.c +24 -12
  172. data/src/core/lib/iomgr/tcp_windows.h +2 -2
  173. data/src/core/lib/iomgr/timer.h +3 -0
  174. data/src/core/lib/iomgr/timer_generic.c +257 -72
  175. data/src/core/lib/iomgr/timer_generic.h +1 -1
  176. data/src/core/lib/iomgr/timer_heap.c +8 -8
  177. data/src/core/lib/iomgr/udp_server.c +54 -24
  178. data/src/core/lib/iomgr/udp_server.h +7 -7
  179. data/src/core/lib/iomgr/unix_sockets_posix.c +1 -1
  180. data/src/core/lib/iomgr/unix_sockets_posix_noop.c +2 -1
  181. data/src/core/lib/iomgr/wakeup_fd_posix.h +1 -1
  182. data/src/core/lib/profiling/basic_timers.c +1 -1
  183. data/src/core/lib/security/credentials/credentials.h +1 -1
  184. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +10 -9
  185. data/src/core/lib/security/credentials/jwt/json_token.c +1 -1
  186. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +2 -2
  187. data/src/core/lib/security/transport/client_auth_filter.c +33 -26
  188. data/src/core/lib/security/transport/secure_endpoint.c +8 -5
  189. data/src/core/lib/security/transport/security_connector.c +37 -37
  190. data/src/core/lib/security/transport/security_connector.h +1 -1
  191. data/src/core/lib/security/transport/security_handshaker.c +15 -12
  192. data/src/core/lib/security/transport/server_auth_filter.c +20 -18
  193. data/src/core/lib/security/transport/tsi_error.c +5 -3
  194. data/src/core/lib/security/transport/tsi_error.h +1 -1
  195. data/src/core/lib/{security/util → slice}/b64.c +21 -6
  196. data/src/core/lib/{security/util → slice}/b64.h +16 -4
  197. data/src/core/lib/slice/slice.c +4 -2
  198. data/src/core/lib/slice/slice_buffer.c +16 -14
  199. data/src/core/lib/support/arena.c +98 -0
  200. data/src/core/{ext/client_channel/initial_connect_string.c → lib/support/arena.h} +17 -15
  201. data/src/core/{ext/client_channel/default_initial_connect_string.c → lib/support/atm.c} +14 -5
  202. data/src/core/lib/support/cpu_linux.c +5 -0
  203. data/src/core/lib/support/sync.c +4 -0
  204. data/src/core/lib/support/time.c +4 -10
  205. data/src/core/lib/support/wrap_memcpy.c +3 -1
  206. data/src/core/lib/surface/call.c +252 -221
  207. data/src/core/lib/surface/channel.c +72 -21
  208. data/src/core/lib/surface/channel.h +8 -0
  209. data/src/core/lib/surface/completion_queue.c +2 -3
  210. data/src/core/lib/surface/completion_queue_factory.c +77 -0
  211. data/src/core/lib/surface/completion_queue_factory.h +51 -0
  212. data/src/core/lib/surface/init_secure.c +3 -1
  213. data/src/core/lib/surface/lame_client.c +18 -14
  214. data/src/core/lib/surface/server.c +43 -41
  215. data/src/core/lib/surface/validate_metadata.c +8 -4
  216. data/src/core/lib/surface/version.c +2 -2
  217. data/src/core/lib/transport/bdp_estimator.h +1 -1
  218. data/src/core/lib/transport/connectivity_state.c +2 -1
  219. data/src/core/lib/transport/error_utils.c +17 -17
  220. data/src/core/lib/transport/error_utils.h +1 -1
  221. data/src/core/lib/transport/metadata_batch.c +6 -7
  222. data/src/core/lib/transport/pid_controller.c +1 -0
  223. data/src/core/lib/transport/service_config.c +12 -0
  224. data/src/core/lib/transport/service_config.h +6 -0
  225. data/src/core/lib/transport/transport.c +29 -17
  226. data/src/core/lib/transport/transport.h +85 -42
  227. data/src/core/lib/transport/transport_impl.h +5 -3
  228. data/src/core/lib/transport/transport_op_string.c +20 -14
  229. data/src/core/plugin_registry/grpc_plugin_registry.c +8 -0
  230. data/src/core/{lib/tsi → tsi}/fake_transport_security.c +2 -2
  231. data/src/core/{lib/tsi → tsi}/fake_transport_security.h +4 -4
  232. data/src/core/{lib/tsi → tsi}/ssl_transport_security.c +40 -79
  233. data/src/core/{lib/tsi → tsi}/ssl_transport_security.h +44 -21
  234. data/src/core/{lib/tsi → tsi}/ssl_types.h +3 -3
  235. data/src/core/{lib/tsi → tsi}/transport_security.c +2 -2
  236. data/src/core/{lib/tsi → tsi}/transport_security.h +4 -4
  237. data/src/core/{lib/tsi → tsi}/transport_security_interface.h +3 -3
  238. data/src/ruby/ext/grpc/extconf.rb +1 -0
  239. data/src/ruby/ext/grpc/rb_call_credentials.c +2 -2
  240. data/src/ruby/ext/grpc/rb_channel.c +520 -93
  241. data/src/ruby/ext/grpc/rb_channel.h +2 -0
  242. data/src/ruby/ext/grpc/rb_channel_credentials.c +3 -0
  243. data/src/ruby/ext/grpc/rb_compression_options.c +5 -2
  244. data/src/ruby/ext/grpc/rb_event_thread.c +6 -6
  245. data/src/ruby/ext/grpc/rb_grpc.c +29 -7
  246. data/src/ruby/ext/grpc/rb_grpc.h +2 -0
  247. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +10 -0
  248. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +15 -0
  249. data/src/ruby/ext/grpc/rb_server.c +5 -3
  250. data/src/ruby/lib/grpc/version.rb +1 -1
  251. data/src/ruby/spec/channel_connection_spec.rb +173 -0
  252. data/src/ruby/spec/channel_spec.rb +29 -0
  253. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +27 -17
  254. data/third_party/cares/ares_build.h +264 -0
  255. data/third_party/cares/cares/ares.h +636 -0
  256. data/third_party/cares/cares/ares__close_sockets.c +61 -0
  257. data/third_party/cares/cares/ares__get_hostent.c +261 -0
  258. data/third_party/cares/cares/ares__read_line.c +73 -0
  259. data/third_party/cares/cares/ares__timeval.c +111 -0
  260. data/third_party/cares/cares/ares_cancel.c +63 -0
  261. data/third_party/cares/cares/ares_create_query.c +202 -0
  262. data/third_party/cares/cares/ares_data.c +221 -0
  263. data/third_party/cares/cares/ares_data.h +72 -0
  264. data/third_party/cares/cares/ares_destroy.c +108 -0
  265. data/third_party/cares/cares/ares_dns.h +103 -0
  266. data/third_party/cares/cares/ares_expand_name.c +205 -0
  267. data/third_party/cares/cares/ares_expand_string.c +70 -0
  268. data/third_party/cares/cares/ares_fds.c +59 -0
  269. data/third_party/cares/cares/ares_free_hostent.c +41 -0
  270. data/third_party/cares/cares/ares_free_string.c +25 -0
  271. data/third_party/cares/cares/ares_getenv.c +30 -0
  272. data/third_party/cares/cares/ares_getenv.h +26 -0
  273. data/third_party/cares/cares/ares_gethostbyaddr.c +294 -0
  274. data/third_party/cares/cares/ares_gethostbyname.c +518 -0
  275. data/third_party/cares/cares/ares_getnameinfo.c +422 -0
  276. data/third_party/cares/cares/ares_getopt.c +122 -0
  277. data/third_party/cares/cares/ares_getopt.h +53 -0
  278. data/third_party/cares/cares/ares_getsock.c +66 -0
  279. data/third_party/cares/cares/ares_inet_net_pton.h +25 -0
  280. data/third_party/cares/cares/ares_init.c +2146 -0
  281. data/third_party/cares/cares/ares_iphlpapi.h +221 -0
  282. data/third_party/cares/cares/ares_ipv6.h +78 -0
  283. data/third_party/cares/cares/ares_library_init.c +167 -0
  284. data/third_party/cares/cares/ares_library_init.h +42 -0
  285. data/third_party/cares/cares/ares_llist.c +63 -0
  286. data/third_party/cares/cares/ares_llist.h +39 -0
  287. data/third_party/cares/cares/ares_mkquery.c +24 -0
  288. data/third_party/cares/cares/ares_nowarn.c +260 -0
  289. data/third_party/cares/cares/ares_nowarn.h +61 -0
  290. data/third_party/cares/cares/ares_options.c +402 -0
  291. data/third_party/cares/cares/ares_parse_a_reply.c +264 -0
  292. data/third_party/cares/cares/ares_parse_aaaa_reply.c +264 -0
  293. data/third_party/cares/cares/ares_parse_mx_reply.c +170 -0
  294. data/third_party/cares/cares/ares_parse_naptr_reply.c +188 -0
  295. data/third_party/cares/cares/ares_parse_ns_reply.c +183 -0
  296. data/third_party/cares/cares/ares_parse_ptr_reply.c +219 -0
  297. data/third_party/cares/cares/ares_parse_soa_reply.c +133 -0
  298. data/third_party/cares/cares/ares_parse_srv_reply.c +179 -0
  299. data/third_party/cares/cares/ares_parse_txt_reply.c +220 -0
  300. data/third_party/cares/cares/ares_platform.c +11035 -0
  301. data/third_party/cares/cares/ares_platform.h +43 -0
  302. data/third_party/cares/cares/ares_private.h +363 -0
  303. data/third_party/cares/cares/ares_process.c +1359 -0
  304. data/third_party/cares/cares/ares_query.c +186 -0
  305. data/third_party/cares/cares/ares_rules.h +125 -0
  306. data/third_party/cares/cares/ares_search.c +316 -0
  307. data/third_party/cares/cares/ares_send.c +131 -0
  308. data/third_party/cares/cares/ares_setup.h +217 -0
  309. data/third_party/cares/cares/ares_strcasecmp.c +66 -0
  310. data/third_party/cares/cares/ares_strcasecmp.h +30 -0
  311. data/third_party/cares/cares/ares_strdup.c +49 -0
  312. data/third_party/cares/cares/ares_strdup.h +24 -0
  313. data/third_party/cares/cares/ares_strerror.c +56 -0
  314. data/third_party/cares/cares/ares_timeout.c +88 -0
  315. data/third_party/cares/cares/ares_version.c +11 -0
  316. data/third_party/cares/cares/ares_version.h +24 -0
  317. data/third_party/cares/cares/ares_writev.c +79 -0
  318. data/third_party/cares/cares/bitncmp.c +59 -0
  319. data/third_party/cares/cares/bitncmp.h +26 -0
  320. data/third_party/cares/cares/config-win32.h +377 -0
  321. data/third_party/cares/cares/inet_net_pton.c +450 -0
  322. data/third_party/cares/cares/inet_ntop.c +208 -0
  323. data/third_party/cares/cares/setup_once.h +554 -0
  324. data/third_party/cares/cares/windows_port.c +22 -0
  325. data/third_party/cares/config_darwin/ares_config.h +523 -0
  326. data/third_party/cares/config_linux/ares_config.h +524 -0
  327. metadata +164 -68
@@ -54,26 +54,36 @@ static grpc_error *handle_response_line(grpc_http_parser *parser) {
54
54
  uint8_t *cur = beg;
55
55
  uint8_t *end = beg + parser->cur_line_length;
56
56
 
57
- if (cur == end || *cur++ != 'H') return GRPC_ERROR_CREATE("Expected 'H'");
58
- if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
59
- if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
60
- if (cur == end || *cur++ != 'P') return GRPC_ERROR_CREATE("Expected 'P'");
61
- if (cur == end || *cur++ != '/') return GRPC_ERROR_CREATE("Expected '/'");
62
- if (cur == end || *cur++ != '1') return GRPC_ERROR_CREATE("Expected '1'");
63
- if (cur == end || *cur++ != '.') return GRPC_ERROR_CREATE("Expected '.'");
57
+ if (cur == end || *cur++ != 'H')
58
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'H'");
59
+ if (cur == end || *cur++ != 'T')
60
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
61
+ if (cur == end || *cur++ != 'T')
62
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
63
+ if (cur == end || *cur++ != 'P')
64
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'P'");
65
+ if (cur == end || *cur++ != '/')
66
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '/'");
67
+ if (cur == end || *cur++ != '1')
68
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '1'");
69
+ if (cur == end || *cur++ != '.')
70
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '.'");
64
71
  if (cur == end || *cur < '0' || *cur++ > '1') {
65
- return GRPC_ERROR_CREATE("Expected HTTP/1.0 or HTTP/1.1");
72
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
73
+ "Expected HTTP/1.0 or HTTP/1.1");
66
74
  }
67
- if (cur == end || *cur++ != ' ') return GRPC_ERROR_CREATE("Expected ' '");
75
+ if (cur == end || *cur++ != ' ')
76
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected ' '");
68
77
  if (cur == end || *cur < '1' || *cur++ > '9')
69
- return GRPC_ERROR_CREATE("Expected status code");
78
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
70
79
  if (cur == end || *cur < '0' || *cur++ > '9')
71
- return GRPC_ERROR_CREATE("Expected status code");
80
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
72
81
  if (cur == end || *cur < '0' || *cur++ > '9')
73
- return GRPC_ERROR_CREATE("Expected status code");
82
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected status code");
74
83
  parser->http.response->status =
75
84
  (cur[-3] - '0') * 100 + (cur[-2] - '0') * 10 + (cur[-1] - '0');
76
- if (cur == end || *cur++ != ' ') return GRPC_ERROR_CREATE("Expected ' '");
85
+ if (cur == end || *cur++ != ' ')
86
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected ' '");
77
87
 
78
88
  /* we don't really care about the status code message */
79
89
 
@@ -89,24 +99,33 @@ static grpc_error *handle_request_line(grpc_http_parser *parser) {
89
99
 
90
100
  while (cur != end && *cur++ != ' ')
91
101
  ;
92
- if (cur == end) return GRPC_ERROR_CREATE("No method on HTTP request line");
102
+ if (cur == end)
103
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
104
+ "No method on HTTP request line");
93
105
  parser->http.request->method = buf2str(beg, (size_t)(cur - beg - 1));
94
106
 
95
107
  beg = cur;
96
108
  while (cur != end && *cur++ != ' ')
97
109
  ;
98
- if (cur == end) return GRPC_ERROR_CREATE("No path on HTTP request line");
110
+ if (cur == end)
111
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No path on HTTP request line");
99
112
  parser->http.request->path = buf2str(beg, (size_t)(cur - beg - 1));
100
113
 
101
- if (cur == end || *cur++ != 'H') return GRPC_ERROR_CREATE("Expected 'H'");
102
- if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
103
- if (cur == end || *cur++ != 'T') return GRPC_ERROR_CREATE("Expected 'T'");
104
- if (cur == end || *cur++ != 'P') return GRPC_ERROR_CREATE("Expected 'P'");
105
- if (cur == end || *cur++ != '/') return GRPC_ERROR_CREATE("Expected '/'");
114
+ if (cur == end || *cur++ != 'H')
115
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'H'");
116
+ if (cur == end || *cur++ != 'T')
117
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
118
+ if (cur == end || *cur++ != 'T')
119
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'T'");
120
+ if (cur == end || *cur++ != 'P')
121
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected 'P'");
122
+ if (cur == end || *cur++ != '/')
123
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Expected '/'");
106
124
  vers_major = (uint8_t)(*cur++ - '1' + 1);
107
125
  ++cur;
108
126
  if (cur == end)
109
- return GRPC_ERROR_CREATE("End of line in HTTP version string");
127
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
128
+ "End of line in HTTP version string");
110
129
  vers_minor = (uint8_t)(*cur++ - '1' + 1);
111
130
 
112
131
  if (vers_major == 1) {
@@ -115,18 +134,19 @@ static grpc_error *handle_request_line(grpc_http_parser *parser) {
115
134
  } else if (vers_minor == 1) {
116
135
  parser->http.request->version = GRPC_HTTP_HTTP11;
117
136
  } else {
118
- return GRPC_ERROR_CREATE(
137
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
119
138
  "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
120
139
  }
121
140
  } else if (vers_major == 2) {
122
141
  if (vers_minor == 0) {
123
142
  parser->http.request->version = GRPC_HTTP_HTTP20;
124
143
  } else {
125
- return GRPC_ERROR_CREATE(
144
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
126
145
  "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
127
146
  }
128
147
  } else {
129
- return GRPC_ERROR_CREATE("Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
148
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
149
+ "Expected one of HTTP/1.0, HTTP/1.1, or HTTP/2.0");
130
150
  }
131
151
 
132
152
  return GRPC_ERROR_NONE;
@@ -139,7 +159,8 @@ static grpc_error *handle_first_line(grpc_http_parser *parser) {
139
159
  case GRPC_HTTP_RESPONSE:
140
160
  return handle_response_line(parser);
141
161
  }
142
- GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
162
+ GPR_UNREACHABLE_CODE(
163
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
143
164
  }
144
165
 
145
166
  static grpc_error *add_header(grpc_http_parser *parser) {
@@ -154,7 +175,8 @@ static grpc_error *add_header(grpc_http_parser *parser) {
154
175
  GPR_ASSERT(cur != end);
155
176
 
156
177
  if (*cur == ' ' || *cur == '\t') {
157
- error = GRPC_ERROR_CREATE("Continued header lines not supported yet");
178
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
179
+ "Continued header lines not supported yet");
158
180
  goto done;
159
181
  }
160
182
 
@@ -162,7 +184,8 @@ static grpc_error *add_header(grpc_http_parser *parser) {
162
184
  cur++;
163
185
  }
164
186
  if (cur == end) {
165
- error = GRPC_ERROR_CREATE("Didn't find ':' in header string");
187
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
188
+ "Didn't find ':' in header string");
166
189
  goto done;
167
190
  }
168
191
  GPR_ASSERT(cur >= beg);
@@ -222,7 +245,8 @@ static grpc_error *finish_line(grpc_http_parser *parser,
222
245
  }
223
246
  break;
224
247
  case GRPC_HTTP_BODY:
225
- GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
248
+ GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
249
+ "Should never reach here"));
226
250
  }
227
251
 
228
252
  parser->cur_line_length = 0;
@@ -240,7 +264,8 @@ static grpc_error *addbyte_body(grpc_http_parser *parser, uint8_t byte) {
240
264
  body_length = &parser->http.request->body_length;
241
265
  body = &parser->http.request->body;
242
266
  } else {
243
- GPR_UNREACHABLE_CODE(return GRPC_ERROR_CREATE("Should never reach here"));
267
+ GPR_UNREACHABLE_CODE(
268
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"));
244
269
  }
245
270
 
246
271
  if (*body_length == parser->body_capacity) {
@@ -286,7 +311,8 @@ static grpc_error *addbyte(grpc_http_parser *parser, uint8_t byte,
286
311
  if (grpc_http1_trace)
287
312
  gpr_log(GPR_ERROR, "HTTP header max line length (%d) exceeded",
288
313
  GRPC_HTTP_PARSER_MAX_HEADER_LENGTH);
289
- return GRPC_ERROR_CREATE("HTTP header max line length exceeded");
314
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
315
+ "HTTP header max line length exceeded");
290
316
  }
291
317
  parser->cur_line[parser->cur_line_length] = byte;
292
318
  parser->cur_line_length++;
@@ -347,7 +373,7 @@ grpc_error *grpc_http_parser_parse(grpc_http_parser *parser, grpc_slice slice,
347
373
 
348
374
  grpc_error *grpc_http_parser_eof(grpc_http_parser *parser) {
349
375
  if (parser->state != GRPC_HTTP_BODY) {
350
- return GRPC_ERROR_CREATE("Did not finish headers");
376
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Did not finish headers");
351
377
  }
352
378
  return GRPC_ERROR_NONE;
353
379
  }
@@ -33,6 +33,7 @@
33
33
 
34
34
  #include "src/core/lib/iomgr/closure.h"
35
35
 
36
+ #include <assert.h>
36
37
  #include <grpc/support/alloc.h>
37
38
  #include <grpc/support/log.h>
38
39
 
@@ -44,6 +45,9 @@ grpc_closure *grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
44
45
  closure->cb = cb;
45
46
  closure->cb_arg = cb_arg;
46
47
  closure->scheduler = scheduler;
48
+ #ifndef NDEBUG
49
+ closure->scheduled = false;
50
+ #endif
47
51
  return closure;
48
52
  }
49
53
 
@@ -124,6 +128,7 @@ void grpc_closure_run(grpc_exec_ctx *exec_ctx, grpc_closure *c,
124
128
  grpc_error *error) {
125
129
  GPR_TIMER_BEGIN("grpc_closure_run", 0);
126
130
  if (c != NULL) {
131
+ assert(c->cb);
127
132
  c->scheduler->vtable->run(exec_ctx, c, error);
128
133
  } else {
129
134
  GRPC_ERROR_UNREF(error);
@@ -135,6 +140,11 @@ void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *c,
135
140
  grpc_error *error) {
136
141
  GPR_TIMER_BEGIN("grpc_closure_sched", 0);
137
142
  if (c != NULL) {
143
+ #ifndef NDEBUG
144
+ GPR_ASSERT(!c->scheduled);
145
+ c->scheduled = true;
146
+ #endif
147
+ assert(c->cb);
138
148
  c->scheduler->vtable->sched(exec_ctx, c, error);
139
149
  } else {
140
150
  GRPC_ERROR_UNREF(error);
@@ -146,6 +156,11 @@ void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx, grpc_closure_list *list) {
146
156
  grpc_closure *c = list->head;
147
157
  while (c != NULL) {
148
158
  grpc_closure *next = c->next_data.next;
159
+ #ifndef NDEBUG
160
+ GPR_ASSERT(!c->scheduled);
161
+ c->scheduled = true;
162
+ #endif
163
+ assert(c->cb);
149
164
  c->scheduler->vtable->sched(exec_ctx, c, c->error_data.error);
150
165
  c = next;
151
166
  }
@@ -99,6 +99,10 @@ struct grpc_closure {
99
99
  grpc_error *error;
100
100
  uintptr_t scratch;
101
101
  } error_data;
102
+
103
+ #ifndef NDEBUG
104
+ bool scheduled;
105
+ #endif
102
106
  };
103
107
 
104
108
  /** Initializes \a closure with \a cb and \a cb_arg. Returns \a closure. */
@@ -33,6 +33,7 @@
33
33
 
34
34
  #include "src/core/lib/iomgr/combiner.h"
35
35
 
36
+ #include <assert.h>
36
37
  #include <string.h>
37
38
 
38
39
  #include <grpc/support/alloc.h>
@@ -216,6 +217,7 @@ static void combiner_exec(grpc_exec_ctx *exec_ctx, grpc_combiner *lock,
216
217
  GPR_DEBUG, "C:%p grpc_combiner_execute c=%p cov=%d last=%" PRIdPTR, lock,
217
218
  cl, covered_by_poller, last));
218
219
  GPR_ASSERT(last & STATE_UNORPHANED); // ensure lock has not been destroyed
220
+ assert(cl->cb);
219
221
  cl->error_data.scratch =
220
222
  pack_error_data((error_data){error, covered_by_poller});
221
223
  if (covered_by_poller) {
@@ -317,6 +319,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
317
319
  GPR_TIMER_BEGIN("combiner.exec1", 0);
318
320
  grpc_closure *cl = (grpc_closure *)n;
319
321
  error_data err = unpack_error_data(cl->error_data.scratch);
322
+ #ifndef NDEBUG
323
+ cl->scheduled = false;
324
+ #endif
320
325
  cl->cb(exec_ctx, cl->cb_arg, err.error);
321
326
  if (err.covered_by_poller) {
322
327
  gpr_atm_no_barrier_fetch_add(&lock->elements_covered_by_poller, -1);
@@ -335,6 +340,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
335
340
  gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c));
336
341
  grpc_closure *next = c->next_data.next;
337
342
  grpc_error *error = c->error_data.error;
343
+ #ifndef NDEBUG
344
+ c->scheduled = false;
345
+ #endif
338
346
  c->cb(exec_ctx, c->cb_arg, error);
339
347
  GRPC_ERROR_UNREF(error);
340
348
  c = next;
@@ -41,8 +41,7 @@ typedef struct {
41
41
  grpc_endpoint *server;
42
42
  } grpc_endpoint_pair;
43
43
 
44
- grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
45
- const char *name, grpc_resource_quota *resource_quota,
46
- size_t read_slice_size);
44
+ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,
45
+ grpc_channel_args *args);
47
46
 
48
47
  #endif /* GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H */
@@ -62,22 +62,25 @@ static void create_sockets(int sv[2]) {
62
62
  GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[1]) == GRPC_ERROR_NONE);
63
63
  }
64
64
 
65
- grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
66
- const char *name, grpc_resource_quota *resource_quota,
67
- size_t read_slice_size) {
65
+ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,
66
+ grpc_channel_args *args) {
68
67
  int sv[2];
69
68
  grpc_endpoint_pair p;
70
69
  char *final_name;
71
70
  create_sockets(sv);
72
71
 
72
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
73
+
73
74
  gpr_asprintf(&final_name, "%s:client", name);
74
- p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name), resource_quota,
75
- read_slice_size, "socketpair-server");
75
+ p.client = grpc_tcp_create(&exec_ctx, grpc_fd_create(sv[1], final_name), args,
76
+ "socketpair-server");
76
77
  gpr_free(final_name);
77
78
  gpr_asprintf(&final_name, "%s:server", name);
78
- p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name), resource_quota,
79
- read_slice_size, "socketpair-client");
79
+ p.server = grpc_tcp_create(&exec_ctx, grpc_fd_create(sv[0], final_name), args,
80
+ "socketpair-client");
80
81
  gpr_free(final_name);
82
+
83
+ grpc_exec_ctx_finish(&exec_ctx);
81
84
  return p;
82
85
  }
83
86
 
@@ -41,9 +41,8 @@
41
41
 
42
42
  #include "src/core/lib/iomgr/endpoint_pair.h"
43
43
 
44
- grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
45
- const char *name, grpc_resource_quota *resource_quota,
46
- size_t read_slice_size) {
44
+ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,
45
+ grpc_channel_args *args) {
47
46
  grpc_endpoint_pair endpoint_pair;
48
47
  // TODO(mlumish): implement this properly under libuv
49
48
  GPR_ASSERT(false &&
@@ -83,15 +83,18 @@ static void create_sockets(SOCKET sv[2]) {
83
83
  }
84
84
 
85
85
  grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
86
- const char *name, grpc_resource_quota *resource_quota,
87
- size_t read_slice_size) {
86
+ const char *name, grpc_channel_args *channel_args) {
88
87
  SOCKET sv[2];
89
88
  grpc_endpoint_pair p;
90
89
  create_sockets(sv);
91
- p.client = grpc_tcp_create(grpc_winsocket_create(sv[1], "endpoint:client"),
92
- resource_quota, "endpoint:server");
93
- p.server = grpc_tcp_create(grpc_winsocket_create(sv[0], "endpoint:server"),
94
- resource_quota, "endpoint:client");
90
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
91
+ p.client = grpc_tcp_create(&exec_ctx,
92
+ grpc_winsocket_create(sv[1], "endpoint:client"),
93
+ channel_args, "endpoint:server");
94
+ p.server = grpc_tcp_create(&exec_ctx,
95
+ grpc_winsocket_create(sv[0], "endpoint:server"),
96
+ channel_args, "endpoint:client");
97
+ grpc_exec_ctx_finish(&exec_ctx);
95
98
  return p;
96
99
  }
97
100
 
@@ -47,46 +47,7 @@
47
47
 
48
48
  #include "src/core/lib/iomgr/error_internal.h"
49
49
  #include "src/core/lib/profiling/timers.h"
50
-
51
- static void destroy_integer(void *key) {}
52
-
53
- static void *copy_integer(void *key) { return key; }
54
-
55
- static long compare_integers(void *key1, void *key2) {
56
- return GPR_ICMP((uintptr_t)key1, (uintptr_t)key2);
57
- }
58
-
59
- static void destroy_string(void *str) { gpr_free(str); }
60
-
61
- static void *copy_string(void *str) { return gpr_strdup(str); }
62
-
63
- static void destroy_err(void *err) { GRPC_ERROR_UNREF(err); }
64
-
65
- static void *copy_err(void *err) { return GRPC_ERROR_REF(err); }
66
-
67
- static void destroy_time(void *tm) { gpr_free(tm); }
68
-
69
- static gpr_timespec *box_time(gpr_timespec tm) {
70
- gpr_timespec *out = gpr_malloc(sizeof(*out));
71
- *out = tm;
72
- return out;
73
- }
74
-
75
- static void *copy_time(void *tm) { return box_time(*(gpr_timespec *)tm); }
76
-
77
- static const gpr_avl_vtable avl_vtable_ints = {destroy_integer, copy_integer,
78
- compare_integers,
79
- destroy_integer, copy_integer};
80
-
81
- static const gpr_avl_vtable avl_vtable_strs = {destroy_integer, copy_integer,
82
- compare_integers, destroy_string,
83
- copy_string};
84
-
85
- static const gpr_avl_vtable avl_vtable_times = {
86
- destroy_integer, copy_integer, compare_integers, destroy_time, copy_time};
87
-
88
- static const gpr_avl_vtable avl_vtable_errs = {
89
- destroy_integer, copy_integer, compare_integers, destroy_err, copy_err};
50
+ #include "src/core/lib/slice/slice_internal.h"
90
51
 
91
52
  static const char *error_int_name(grpc_error_ints key) {
92
53
  switch (key) {
@@ -120,6 +81,8 @@ static const char *error_int_name(grpc_error_ints key) {
120
81
  return "limit";
121
82
  case GRPC_ERROR_INT_OCCURRED_DURING_WRITE:
122
83
  return "occurred_during_write";
84
+ case GRPC_ERROR_INT_MAX:
85
+ GPR_UNREACHABLE_CODE(return "unknown");
123
86
  }
124
87
  GPR_UNREACHABLE_CODE(return "unknown");
125
88
  }
@@ -150,6 +113,8 @@ static const char *error_str_name(grpc_error_strs key) {
150
113
  return "filename";
151
114
  case GRPC_ERROR_STR_QUEUED_BUFFERS:
152
115
  return "queued_buffers";
116
+ case GRPC_ERROR_STR_MAX:
117
+ GPR_UNREACHABLE_CODE(return "unknown");
153
118
  }
154
119
  GPR_UNREACHABLE_CODE(return "unknown");
155
120
  }
@@ -158,6 +123,8 @@ static const char *error_time_name(grpc_error_times key) {
158
123
  switch (key) {
159
124
  case GRPC_ERROR_TIME_CREATED:
160
125
  return "created";
126
+ case GRPC_ERROR_TIME_MAX:
127
+ GPR_UNREACHABLE_CODE(return "unknown");
161
128
  }
162
129
  GPR_UNREACHABLE_CODE(return "unknown");
163
130
  }
@@ -172,25 +139,51 @@ grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line,
172
139
  const char *func) {
173
140
  if (grpc_error_is_special(err)) return err;
174
141
  gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
175
- err->refs.count, err->refs.count + 1, file, line, func);
176
- gpr_ref(&err->refs);
142
+ gpr_atm_no_barrier_load(&err->atomics.refs.count),
143
+ gpr_atm_no_barrier_load(&err->atomics.refs.count) + 1, file, line,
144
+ func);
145
+ gpr_ref(&err->atomics.refs);
177
146
  return err;
178
147
  }
179
148
  #else
180
149
  grpc_error *grpc_error_ref(grpc_error *err) {
181
150
  if (grpc_error_is_special(err)) return err;
182
- gpr_ref(&err->refs);
151
+ gpr_ref(&err->atomics.refs);
183
152
  return err;
184
153
  }
185
154
  #endif
186
155
 
156
+ static void unref_errs(grpc_error *err) {
157
+ uint8_t slot = err->first_err;
158
+ while (slot != UINT8_MAX) {
159
+ grpc_linked_error *lerr = (grpc_linked_error *)(err->arena + slot);
160
+ GRPC_ERROR_UNREF(lerr->err);
161
+ GPR_ASSERT(err->last_err == slot ? lerr->next == UINT8_MAX
162
+ : lerr->next != UINT8_MAX);
163
+ slot = lerr->next;
164
+ }
165
+ }
166
+
167
+ static void unref_slice(grpc_slice slice) {
168
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
169
+ grpc_slice_unref_internal(&exec_ctx, slice);
170
+ grpc_exec_ctx_finish(&exec_ctx);
171
+ }
172
+
173
+ static void unref_strs(grpc_error *err) {
174
+ for (size_t which = 0; which < GRPC_ERROR_STR_MAX; ++which) {
175
+ uint8_t slot = err->strs[which];
176
+ if (slot != UINT8_MAX) {
177
+ unref_slice(*(grpc_slice *)(err->arena + slot));
178
+ }
179
+ }
180
+ }
181
+
187
182
  static void error_destroy(grpc_error *err) {
188
183
  GPR_ASSERT(!grpc_error_is_special(err));
189
- gpr_avl_unref(err->ints);
190
- gpr_avl_unref(err->strs);
191
- gpr_avl_unref(err->errs);
192
- gpr_avl_unref(err->times);
193
- gpr_free((void *)gpr_atm_acq_load(&err->error_string));
184
+ unref_errs(err);
185
+ unref_strs(err);
186
+ gpr_free((void *)gpr_atm_acq_load(&err->atomics.error_string));
194
187
  gpr_free(err);
195
188
  }
196
189
 
@@ -199,81 +192,230 @@ void grpc_error_unref(grpc_error *err, const char *file, int line,
199
192
  const char *func) {
200
193
  if (grpc_error_is_special(err)) return;
201
194
  gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err,
202
- err->refs.count, err->refs.count - 1, file, line, func);
203
- if (gpr_unref(&err->refs)) {
195
+ gpr_atm_no_barrier_load(&err->atomics.refs.count),
196
+ gpr_atm_no_barrier_load(&err->atomics.refs.count) - 1, file, line,
197
+ func);
198
+ if (gpr_unref(&err->atomics.refs)) {
204
199
  error_destroy(err);
205
200
  }
206
201
  }
207
202
  #else
208
203
  void grpc_error_unref(grpc_error *err) {
209
204
  if (grpc_error_is_special(err)) return;
210
- if (gpr_unref(&err->refs)) {
205
+ if (gpr_unref(&err->atomics.refs)) {
211
206
  error_destroy(err);
212
207
  }
213
208
  }
214
209
  #endif
215
210
 
216
- grpc_error *grpc_error_create(const char *file, int line, const char *desc,
211
+ static uint8_t get_placement(grpc_error **err, size_t size) {
212
+ GPR_ASSERT(*err);
213
+ uint8_t slots = (uint8_t)(size / sizeof(intptr_t));
214
+ if ((*err)->arena_size + slots > (*err)->arena_capacity) {
215
+ (*err)->arena_capacity =
216
+ (uint8_t)GPR_MIN(UINT8_MAX - 1, (3 * (*err)->arena_capacity / 2));
217
+ if ((*err)->arena_size + slots > (*err)->arena_capacity) {
218
+ return UINT8_MAX;
219
+ }
220
+ *err = gpr_realloc(
221
+ *err, sizeof(grpc_error) + (*err)->arena_capacity * sizeof(intptr_t));
222
+ }
223
+ uint8_t placement = (*err)->arena_size;
224
+ (*err)->arena_size = (uint8_t)((*err)->arena_size + slots);
225
+ return placement;
226
+ }
227
+
228
+ static void internal_set_int(grpc_error **err, grpc_error_ints which,
229
+ intptr_t value) {
230
+ uint8_t slot = (*err)->ints[which];
231
+ if (slot == UINT8_MAX) {
232
+ slot = get_placement(err, sizeof(value));
233
+ if (slot == UINT8_MAX) {
234
+ gpr_log(GPR_ERROR, "Error %p is full, dropping int {\"%s\":%" PRIiPTR "}",
235
+ *err, error_int_name(which), value);
236
+ return;
237
+ }
238
+ }
239
+ (*err)->ints[which] = slot;
240
+ (*err)->arena[slot] = value;
241
+ }
242
+
243
+ static void internal_set_str(grpc_error **err, grpc_error_strs which,
244
+ grpc_slice value) {
245
+ uint8_t slot = (*err)->strs[which];
246
+ if (slot == UINT8_MAX) {
247
+ slot = get_placement(err, sizeof(value));
248
+ if (slot == UINT8_MAX) {
249
+ const char *str = grpc_slice_to_c_string(value);
250
+ gpr_log(GPR_ERROR, "Error %p is full, dropping string {\"%s\":\"%s\"}",
251
+ *err, error_str_name(which), str);
252
+ gpr_free((void *)str);
253
+ return;
254
+ }
255
+ } else {
256
+ unref_slice(*(grpc_slice *)((*err)->arena + slot));
257
+ }
258
+ (*err)->strs[which] = slot;
259
+ memcpy((*err)->arena + slot, &value, sizeof(value));
260
+ }
261
+
262
+ static char *fmt_time(gpr_timespec tm);
263
+ static void internal_set_time(grpc_error **err, grpc_error_times which,
264
+ gpr_timespec value) {
265
+ uint8_t slot = (*err)->times[which];
266
+ if (slot == UINT8_MAX) {
267
+ slot = get_placement(err, sizeof(value));
268
+ if (slot == UINT8_MAX) {
269
+ const char *time_str = fmt_time(value);
270
+ gpr_log(GPR_ERROR, "Error %p is full, dropping \"%s\":\"%s\"}", *err,
271
+ error_time_name(which), time_str);
272
+ gpr_free((void *)time_str);
273
+ return;
274
+ }
275
+ }
276
+ (*err)->times[which] = slot;
277
+ memcpy((*err)->arena + slot, &value, sizeof(value));
278
+ }
279
+
280
+ static void internal_add_error(grpc_error **err, grpc_error *new) {
281
+ grpc_linked_error new_last = {new, UINT8_MAX};
282
+ uint8_t slot = get_placement(err, sizeof(grpc_linked_error));
283
+ if (slot == UINT8_MAX) {
284
+ gpr_log(GPR_ERROR, "Error %p is full, dropping error %p = %s", *err, new,
285
+ grpc_error_string(new));
286
+ GRPC_ERROR_UNREF(new);
287
+ return;
288
+ }
289
+ if ((*err)->first_err == UINT8_MAX) {
290
+ GPR_ASSERT((*err)->last_err == UINT8_MAX);
291
+ (*err)->last_err = slot;
292
+ (*err)->first_err = slot;
293
+ } else {
294
+ GPR_ASSERT((*err)->last_err != UINT8_MAX);
295
+ grpc_linked_error *old_last =
296
+ (grpc_linked_error *)((*err)->arena + (*err)->last_err);
297
+ old_last->next = slot;
298
+ (*err)->last_err = slot;
299
+ }
300
+ memcpy((*err)->arena + slot, &new_last, sizeof(grpc_linked_error));
301
+ }
302
+
303
+ #define SLOTS_PER_INT (sizeof(intptr_t) / sizeof(intptr_t))
304
+ #define SLOTS_PER_STR (sizeof(grpc_slice) / sizeof(intptr_t))
305
+ #define SLOTS_PER_TIME (sizeof(gpr_timespec) / sizeof(intptr_t))
306
+ #define SLOTS_PER_LINKED_ERROR (sizeof(grpc_linked_error) / sizeof(intptr_t))
307
+
308
+ // size of storing one int and two slices and a timespec. For line, desc, file,
309
+ // and time created
310
+ #define DEFAULT_ERROR_CAPACITY \
311
+ (SLOTS_PER_INT + (SLOTS_PER_STR * 2) + SLOTS_PER_TIME)
312
+
313
+ // It is very common to include and extra int and string in an error
314
+ #define SURPLUS_CAPACITY (2 * SLOTS_PER_INT + SLOTS_PER_TIME)
315
+
316
+ grpc_error *grpc_error_create(grpc_slice file, int line, grpc_slice desc,
217
317
  grpc_error **referencing,
218
318
  size_t num_referencing) {
219
319
  GPR_TIMER_BEGIN("grpc_error_create", 0);
220
- grpc_error *err = gpr_malloc(sizeof(*err));
320
+ uint8_t initial_arena_capacity = (uint8_t)(
321
+ DEFAULT_ERROR_CAPACITY +
322
+ (uint8_t)(num_referencing * SLOTS_PER_LINKED_ERROR) + SURPLUS_CAPACITY);
323
+ grpc_error *err =
324
+ gpr_malloc(sizeof(*err) + initial_arena_capacity * sizeof(intptr_t));
221
325
  if (err == NULL) { // TODO(ctiller): make gpr_malloc return NULL
222
326
  return GRPC_ERROR_OOM;
223
327
  }
224
328
  #ifdef GRPC_ERROR_REFCOUNT_DEBUG
225
329
  gpr_log(GPR_DEBUG, "%p create [%s:%d]", err, file, line);
226
330
  #endif
227
- err->ints = gpr_avl_add(gpr_avl_create(&avl_vtable_ints),
228
- (void *)(uintptr_t)GRPC_ERROR_INT_FILE_LINE,
229
- (void *)(uintptr_t)line);
230
- err->strs = gpr_avl_add(
231
- gpr_avl_add(gpr_avl_create(&avl_vtable_strs),
232
- (void *)(uintptr_t)GRPC_ERROR_STR_FILE, gpr_strdup(file)),
233
- (void *)(uintptr_t)GRPC_ERROR_STR_DESCRIPTION, gpr_strdup(desc));
234
- err->errs = gpr_avl_create(&avl_vtable_errs);
235
- err->next_err = 0;
236
- for (size_t i = 0; i < num_referencing; i++) {
331
+
332
+ err->arena_size = 0;
333
+ err->arena_capacity = initial_arena_capacity;
334
+ err->first_err = UINT8_MAX;
335
+ err->last_err = UINT8_MAX;
336
+
337
+ memset(err->ints, UINT8_MAX, GRPC_ERROR_INT_MAX);
338
+ memset(err->strs, UINT8_MAX, GRPC_ERROR_STR_MAX);
339
+ memset(err->times, UINT8_MAX, GRPC_ERROR_TIME_MAX);
340
+
341
+ internal_set_int(&err, GRPC_ERROR_INT_FILE_LINE, line);
342
+ internal_set_str(&err, GRPC_ERROR_STR_FILE, file);
343
+ internal_set_str(&err, GRPC_ERROR_STR_DESCRIPTION, desc);
344
+
345
+ for (size_t i = 0; i < num_referencing; ++i) {
237
346
  if (referencing[i] == GRPC_ERROR_NONE) continue;
238
- err->errs = gpr_avl_add(err->errs, (void *)(err->next_err++),
239
- GRPC_ERROR_REF(referencing[i]));
240
- }
241
- err->times = gpr_avl_add(gpr_avl_create(&avl_vtable_times),
242
- (void *)(uintptr_t)GRPC_ERROR_TIME_CREATED,
243
- box_time(gpr_now(GPR_CLOCK_REALTIME)));
244
- gpr_atm_no_barrier_store(&err->error_string, 0);
245
- gpr_ref_init(&err->refs, 1);
347
+ internal_add_error(
348
+ &err,
349
+ GRPC_ERROR_REF(
350
+ referencing[i])); // TODO(ncteisen), change ownership semantics
351
+ }
352
+
353
+ internal_set_time(&err, GRPC_ERROR_TIME_CREATED, gpr_now(GPR_CLOCK_REALTIME));
354
+
355
+ gpr_atm_no_barrier_store(&err->atomics.error_string, 0);
356
+ gpr_ref_init(&err->atomics.refs, 1);
246
357
  GPR_TIMER_END("grpc_error_create", 0);
247
358
  return err;
248
359
  }
249
360
 
361
+ static void ref_strs(grpc_error *err) {
362
+ for (size_t i = 0; i < GRPC_ERROR_STR_MAX; ++i) {
363
+ uint8_t slot = err->strs[i];
364
+ if (slot != UINT8_MAX) {
365
+ grpc_slice_ref_internal(*(grpc_slice *)(err->arena + slot));
366
+ }
367
+ }
368
+ }
369
+
370
+ static void ref_errs(grpc_error *err) {
371
+ uint8_t slot = err->first_err;
372
+ while (slot != UINT8_MAX) {
373
+ grpc_linked_error *lerr = (grpc_linked_error *)(err->arena + slot);
374
+ GRPC_ERROR_REF(lerr->err);
375
+ slot = lerr->next;
376
+ }
377
+ }
378
+
250
379
  static grpc_error *copy_error_and_unref(grpc_error *in) {
251
380
  GPR_TIMER_BEGIN("copy_error_and_unref", 0);
252
381
  grpc_error *out;
253
382
  if (grpc_error_is_special(in)) {
254
- if (in == GRPC_ERROR_NONE)
255
- out = grpc_error_set_int(GRPC_ERROR_CREATE("no error"),
256
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK);
257
- else if (in == GRPC_ERROR_OOM)
258
- out = GRPC_ERROR_CREATE("oom");
259
- else if (in == GRPC_ERROR_CANCELLED)
260
- out =
261
- grpc_error_set_int(GRPC_ERROR_CREATE("cancelled"),
262
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED);
263
- else
264
- out = GRPC_ERROR_CREATE("unknown");
383
+ out = GRPC_ERROR_CREATE_FROM_STATIC_STRING("unknown");
384
+ if (in == GRPC_ERROR_NONE) {
385
+ internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
386
+ grpc_slice_from_static_string("no error"));
387
+ internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK);
388
+ } else if (in == GRPC_ERROR_OOM) {
389
+ internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
390
+ grpc_slice_from_static_string("oom"));
391
+ } else if (in == GRPC_ERROR_CANCELLED) {
392
+ internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION,
393
+ grpc_slice_from_static_string("cancelled"));
394
+ internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED);
395
+ }
396
+ } else if (gpr_ref_is_unique(&in->atomics.refs)) {
397
+ out = in;
265
398
  } else {
266
- out = gpr_malloc(sizeof(*out));
399
+ uint8_t new_arena_capacity = in->arena_capacity;
400
+ // the returned err will be added to, so we ensure this is room to avoid
401
+ // unneeded allocations.
402
+ if (in->arena_capacity - in->arena_size < (uint8_t)SLOTS_PER_STR) {
403
+ new_arena_capacity = (uint8_t)(3 * new_arena_capacity / 2);
404
+ }
405
+ out = gpr_malloc(sizeof(*in) + new_arena_capacity * sizeof(intptr_t));
267
406
  #ifdef GRPC_ERROR_REFCOUNT_DEBUG
268
407
  gpr_log(GPR_DEBUG, "%p create copying %p", out, in);
269
408
  #endif
270
- out->ints = gpr_avl_ref(in->ints);
271
- out->strs = gpr_avl_ref(in->strs);
272
- out->errs = gpr_avl_ref(in->errs);
273
- out->times = gpr_avl_ref(in->times);
274
- gpr_atm_no_barrier_store(&out->error_string, 0);
275
- out->next_err = in->next_err;
276
- gpr_ref_init(&out->refs, 1);
409
+ // bulk memcpy of the rest of the struct.
410
+ size_t skip = sizeof(&out->atomics);
411
+ memcpy((void *)((uintptr_t)out + skip), (void *)((uintptr_t)in + skip),
412
+ sizeof(*in) + (in->arena_size * sizeof(intptr_t)) - skip);
413
+ // manually set the atomics and the new capacity
414
+ gpr_atm_no_barrier_store(&out->atomics.error_string, 0);
415
+ gpr_ref_init(&out->atomics.refs, 1);
416
+ out->arena_capacity = new_arena_capacity;
417
+ ref_strs(out);
418
+ ref_errs(out);
277
419
  GRPC_ERROR_UNREF(in);
278
420
  }
279
421
  GPR_TIMER_END("copy_error_and_unref", 0);
@@ -284,7 +426,7 @@ grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which,
284
426
  intptr_t value) {
285
427
  GPR_TIMER_BEGIN("grpc_error_set_int", 0);
286
428
  grpc_error *new = copy_error_and_unref(src);
287
- new->ints = gpr_avl_add(new->ints, (void *)(uintptr_t)which, (void *)value);
429
+ internal_set_int(&new, which, value);
288
430
  GPR_TIMER_END("grpc_error_set_int", 0);
289
431
  return new;
290
432
  }
@@ -295,14 +437,13 @@ typedef struct {
295
437
  const char *msg;
296
438
  } special_error_status_map;
297
439
  static special_error_status_map error_status_map[] = {
298
- {GRPC_ERROR_NONE, GRPC_STATUS_OK, NULL},
440
+ {GRPC_ERROR_NONE, GRPC_STATUS_OK, ""},
299
441
  {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "Cancelled"},
300
442
  {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"},
301
443
  };
302
444
 
303
445
  bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
304
446
  GPR_TIMER_BEGIN("grpc_error_get_int", 0);
305
- void *pp;
306
447
  if (grpc_error_is_special(err)) {
307
448
  if (which == GRPC_ERROR_INT_GRPC_STATUS) {
308
449
  for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) {
@@ -316,8 +457,9 @@ bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
316
457
  GPR_TIMER_END("grpc_error_get_int", 0);
317
458
  return false;
318
459
  }
319
- if (gpr_avl_maybe_get(err->ints, (void *)(uintptr_t)which, &pp)) {
320
- if (p != NULL) *p = (intptr_t)pp;
460
+ uint8_t slot = err->ints[which];
461
+ if (slot != UINT8_MAX) {
462
+ if (p != NULL) *p = err->arena[slot];
321
463
  GPR_TIMER_END("grpc_error_get_int", 0);
322
464
  return true;
323
465
  }
@@ -326,33 +468,40 @@ bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) {
326
468
  }
327
469
 
328
470
  grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
329
- const char *value) {
471
+ grpc_slice str) {
330
472
  GPR_TIMER_BEGIN("grpc_error_set_str", 0);
331
473
  grpc_error *new = copy_error_and_unref(src);
332
- new->strs =
333
- gpr_avl_add(new->strs, (void *)(uintptr_t)which, gpr_strdup(value));
474
+ internal_set_str(&new, which, str);
334
475
  GPR_TIMER_END("grpc_error_set_str", 0);
335
476
  return new;
336
477
  }
337
478
 
338
- const char *grpc_error_get_str(grpc_error *err, grpc_error_strs which) {
479
+ bool grpc_error_get_str(grpc_error *err, grpc_error_strs which,
480
+ grpc_slice *str) {
339
481
  if (grpc_error_is_special(err)) {
340
482
  if (which == GRPC_ERROR_STR_GRPC_MESSAGE) {
341
483
  for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) {
342
484
  if (error_status_map[i].error == err) {
343
- return error_status_map[i].msg;
485
+ *str = grpc_slice_from_static_string(error_status_map[i].msg);
486
+ return true;
344
487
  }
345
488
  }
346
489
  }
347
- return NULL;
490
+ return false;
491
+ }
492
+ uint8_t slot = err->strs[which];
493
+ if (slot != UINT8_MAX) {
494
+ *str = *(grpc_slice *)(err->arena + slot);
495
+ return true;
496
+ } else {
497
+ return false;
348
498
  }
349
- return gpr_avl_get(err->strs, (void *)(uintptr_t)which);
350
499
  }
351
500
 
352
501
  grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) {
353
502
  GPR_TIMER_BEGIN("grpc_error_add_child", 0);
354
503
  grpc_error *new = copy_error_and_unref(src);
355
- new->errs = gpr_avl_add(new->errs, (void *)(new->next_err++), child);
504
+ internal_add_error(&new, child);
356
505
  GPR_TIMER_END("grpc_error_add_child", 0);
357
506
  return new;
358
507
  }
@@ -372,42 +521,6 @@ typedef struct {
372
521
  size_t cap_kvs;
373
522
  } kv_pairs;
374
523
 
375
- static void append_kv(kv_pairs *kvs, char *key, char *value) {
376
- if (kvs->num_kvs == kvs->cap_kvs) {
377
- kvs->cap_kvs = GPR_MAX(3 * kvs->cap_kvs / 2, 4);
378
- kvs->kvs = gpr_realloc(kvs->kvs, sizeof(*kvs->kvs) * kvs->cap_kvs);
379
- }
380
- kvs->kvs[kvs->num_kvs].key = key;
381
- kvs->kvs[kvs->num_kvs].value = value;
382
- kvs->num_kvs++;
383
- }
384
-
385
- static void collect_kvs(gpr_avl_node *node, char *key(void *k),
386
- char *fmt(void *v), kv_pairs *kvs) {
387
- if (node == NULL) return;
388
- append_kv(kvs, key(node->key), fmt(node->value));
389
- collect_kvs(node->left, key, fmt, kvs);
390
- collect_kvs(node->right, key, fmt, kvs);
391
- }
392
-
393
- static char *key_int(void *p) {
394
- return gpr_strdup(error_int_name((grpc_error_ints)(uintptr_t)p));
395
- }
396
-
397
- static char *key_str(void *p) {
398
- return gpr_strdup(error_str_name((grpc_error_strs)(uintptr_t)p));
399
- }
400
-
401
- static char *key_time(void *p) {
402
- return gpr_strdup(error_time_name((grpc_error_times)(uintptr_t)p));
403
- }
404
-
405
- static char *fmt_int(void *p) {
406
- char *s;
407
- gpr_asprintf(&s, "%" PRIdPTR, (intptr_t)p);
408
- return s;
409
- }
410
-
411
524
  static void append_chr(char c, char **s, size_t *sz, size_t *cap) {
412
525
  if (*sz == *cap) {
413
526
  *cap = GPR_MAX(8, 3 * *cap / 2);
@@ -422,13 +535,14 @@ static void append_str(const char *str, char **s, size_t *sz, size_t *cap) {
422
535
  }
423
536
  }
424
537
 
425
- static void append_esc_str(const char *str, char **s, size_t *sz, size_t *cap) {
538
+ static void append_esc_str(const uint8_t *str, size_t len, char **s, size_t *sz,
539
+ size_t *cap) {
426
540
  static const char *hex = "0123456789abcdef";
427
541
  append_chr('"', s, sz, cap);
428
- for (const uint8_t *c = (const uint8_t *)str; *c; c++) {
429
- if (*c < 32 || *c >= 127) {
542
+ for (size_t i = 0; i < len; i++, str++) {
543
+ if (*str < 32 || *str >= 127) {
430
544
  append_chr('\\', s, sz, cap);
431
- switch (*c) {
545
+ switch (*str) {
432
546
  case '\b':
433
547
  append_chr('b', s, sz, cap);
434
548
  break;
@@ -448,28 +562,76 @@ static void append_esc_str(const char *str, char **s, size_t *sz, size_t *cap) {
448
562
  append_chr('u', s, sz, cap);
449
563
  append_chr('0', s, sz, cap);
450
564
  append_chr('0', s, sz, cap);
451
- append_chr(hex[*c >> 4], s, sz, cap);
452
- append_chr(hex[*c & 0x0f], s, sz, cap);
565
+ append_chr(hex[*str >> 4], s, sz, cap);
566
+ append_chr(hex[*str & 0x0f], s, sz, cap);
453
567
  break;
454
568
  }
455
569
  } else {
456
- append_chr((char)*c, s, sz, cap);
570
+ append_chr((char)*str, s, sz, cap);
457
571
  }
458
572
  }
459
573
  append_chr('"', s, sz, cap);
460
574
  }
461
575
 
462
- static char *fmt_str(void *p) {
576
+ static void append_kv(kv_pairs *kvs, char *key, char *value) {
577
+ if (kvs->num_kvs == kvs->cap_kvs) {
578
+ kvs->cap_kvs = GPR_MAX(3 * kvs->cap_kvs / 2, 4);
579
+ kvs->kvs = gpr_realloc(kvs->kvs, sizeof(*kvs->kvs) * kvs->cap_kvs);
580
+ }
581
+ kvs->kvs[kvs->num_kvs].key = key;
582
+ kvs->kvs[kvs->num_kvs].value = value;
583
+ kvs->num_kvs++;
584
+ }
585
+
586
+ static char *key_int(grpc_error_ints which) {
587
+ return gpr_strdup(error_int_name(which));
588
+ }
589
+
590
+ static char *fmt_int(intptr_t p) {
591
+ char *s;
592
+ gpr_asprintf(&s, "%" PRIdPTR, p);
593
+ return s;
594
+ }
595
+
596
+ static void collect_ints_kvs(grpc_error *err, kv_pairs *kvs) {
597
+ for (size_t which = 0; which < GRPC_ERROR_INT_MAX; ++which) {
598
+ uint8_t slot = err->ints[which];
599
+ if (slot != UINT8_MAX) {
600
+ append_kv(kvs, key_int((grpc_error_ints)which),
601
+ fmt_int(err->arena[slot]));
602
+ }
603
+ }
604
+ }
605
+
606
+ static char *key_str(grpc_error_strs which) {
607
+ return gpr_strdup(error_str_name(which));
608
+ }
609
+
610
+ static char *fmt_str(grpc_slice slice) {
463
611
  char *s = NULL;
464
612
  size_t sz = 0;
465
613
  size_t cap = 0;
466
- append_esc_str(p, &s, &sz, &cap);
614
+ append_esc_str((const uint8_t *)GRPC_SLICE_START_PTR(slice),
615
+ GRPC_SLICE_LENGTH(slice), &s, &sz, &cap);
467
616
  append_chr(0, &s, &sz, &cap);
468
617
  return s;
469
618
  }
470
619
 
471
- static char *fmt_time(void *p) {
472
- gpr_timespec tm = *(gpr_timespec *)p;
620
+ static void collect_strs_kvs(grpc_error *err, kv_pairs *kvs) {
621
+ for (size_t which = 0; which < GRPC_ERROR_STR_MAX; ++which) {
622
+ uint8_t slot = err->strs[which];
623
+ if (slot != UINT8_MAX) {
624
+ append_kv(kvs, key_str((grpc_error_strs)which),
625
+ fmt_str(*(grpc_slice *)(err->arena + slot)));
626
+ }
627
+ }
628
+ }
629
+
630
+ static char *key_time(grpc_error_times which) {
631
+ return gpr_strdup(error_time_name(which));
632
+ }
633
+
634
+ static char *fmt_time(gpr_timespec tm) {
473
635
  char *out;
474
636
  char *pfx = "!!";
475
637
  switch (tm.clock_type) {
@@ -490,24 +652,37 @@ static char *fmt_time(void *p) {
490
652
  return out;
491
653
  }
492
654
 
493
- static void add_errs(gpr_avl_node *n, char **s, size_t *sz, size_t *cap,
494
- bool *first) {
495
- if (n == NULL) return;
496
- add_errs(n->left, s, sz, cap, first);
497
- if (!*first) append_chr(',', s, sz, cap);
498
- *first = false;
499
- const char *e = grpc_error_string(n->value);
500
- append_str(e, s, sz, cap);
501
- add_errs(n->right, s, sz, cap, first);
655
+ static void collect_times_kvs(grpc_error *err, kv_pairs *kvs) {
656
+ for (size_t which = 0; which < GRPC_ERROR_TIME_MAX; ++which) {
657
+ uint8_t slot = err->times[which];
658
+ if (slot != UINT8_MAX) {
659
+ append_kv(kvs, key_time((grpc_error_times)which),
660
+ fmt_time(*(gpr_timespec *)(err->arena + slot)));
661
+ }
662
+ }
663
+ }
664
+
665
+ static void add_errs(grpc_error *err, char **s, size_t *sz, size_t *cap) {
666
+ uint8_t slot = err->first_err;
667
+ bool first = true;
668
+ while (slot != UINT8_MAX) {
669
+ grpc_linked_error *lerr = (grpc_linked_error *)(err->arena + slot);
670
+ if (!first) append_chr(',', s, sz, cap);
671
+ first = false;
672
+ const char *e = grpc_error_string(lerr->err);
673
+ append_str(e, s, sz, cap);
674
+ GPR_ASSERT(err->last_err == slot ? lerr->next == UINT8_MAX
675
+ : lerr->next != UINT8_MAX);
676
+ slot = lerr->next;
677
+ }
502
678
  }
503
679
 
504
680
  static char *errs_string(grpc_error *err) {
505
681
  char *s = NULL;
506
682
  size_t sz = 0;
507
683
  size_t cap = 0;
508
- bool first = true;
509
684
  append_chr('[', &s, &sz, &cap);
510
- add_errs(err->errs.root, &s, &sz, &cap, &first);
685
+ add_errs(err, &s, &sz, &cap);
511
686
  append_chr(']', &s, &sz, &cap);
512
687
  append_chr(0, &s, &sz, &cap);
513
688
  return s;
@@ -527,7 +702,8 @@ static char *finish_kvs(kv_pairs *kvs) {
527
702
  append_chr('{', &s, &sz, &cap);
528
703
  for (size_t i = 0; i < kvs->num_kvs; i++) {
529
704
  if (i != 0) append_chr(',', &s, &sz, &cap);
530
- append_esc_str(kvs->kvs[i].key, &s, &sz, &cap);
705
+ append_esc_str((const uint8_t *)kvs->kvs[i].key, strlen(kvs->kvs[i].key),
706
+ &s, &sz, &cap);
531
707
  gpr_free(kvs->kvs[i].key);
532
708
  append_chr(':', &s, &sz, &cap);
533
709
  append_str(kvs->kvs[i].value, &s, &sz, &cap);
@@ -546,7 +722,7 @@ const char *grpc_error_string(grpc_error *err) {
546
722
  if (err == GRPC_ERROR_OOM) return oom_error_string;
547
723
  if (err == GRPC_ERROR_CANCELLED) return cancelled_error_string;
548
724
 
549
- void *p = (void *)gpr_atm_acq_load(&err->error_string);
725
+ void *p = (void *)gpr_atm_acq_load(&err->atomics.error_string);
550
726
  if (p != NULL) {
551
727
  GPR_TIMER_END("grpc_error_string", 0);
552
728
  return p;
@@ -555,10 +731,10 @@ const char *grpc_error_string(grpc_error *err) {
555
731
  kv_pairs kvs;
556
732
  memset(&kvs, 0, sizeof(kvs));
557
733
 
558
- collect_kvs(err->ints.root, key_int, fmt_int, &kvs);
559
- collect_kvs(err->strs.root, key_str, fmt_str, &kvs);
560
- collect_kvs(err->times.root, key_time, fmt_time, &kvs);
561
- if (!gpr_avl_is_empty(err->errs)) {
734
+ collect_ints_kvs(err, &kvs);
735
+ collect_strs_kvs(err, &kvs);
736
+ collect_times_kvs(err, &kvs);
737
+ if (err->first_err != UINT8_MAX) {
562
738
  append_kv(&kvs, gpr_strdup("referenced_errors"), errs_string(err));
563
739
  }
564
740
 
@@ -566,9 +742,9 @@ const char *grpc_error_string(grpc_error *err) {
566
742
 
567
743
  char *out = finish_kvs(&kvs);
568
744
 
569
- if (!gpr_atm_rel_cas(&err->error_string, 0, (gpr_atm)out)) {
745
+ if (!gpr_atm_rel_cas(&err->atomics.error_string, 0, (gpr_atm)out)) {
570
746
  gpr_free(out);
571
- out = (char *)gpr_atm_no_barrier_load(&err->error_string);
747
+ out = (char *)gpr_atm_no_barrier_load(&err->atomics.error_string);
572
748
  }
573
749
 
574
750
  GPR_TIMER_END("grpc_error_string", 0);
@@ -579,10 +755,14 @@ grpc_error *grpc_os_error(const char *file, int line, int err,
579
755
  const char *call_name) {
580
756
  return grpc_error_set_str(
581
757
  grpc_error_set_str(
582
- grpc_error_set_int(grpc_error_create(file, line, "OS Error", NULL, 0),
583
- GRPC_ERROR_INT_ERRNO, err),
584
- GRPC_ERROR_STR_OS_ERROR, strerror(err)),
585
- GRPC_ERROR_STR_SYSCALL, call_name);
758
+ grpc_error_set_int(
759
+ grpc_error_create(grpc_slice_from_static_string(file), line,
760
+ grpc_slice_from_static_string("OS Error"), NULL,
761
+ 0),
762
+ GRPC_ERROR_INT_ERRNO, err),
763
+ GRPC_ERROR_STR_OS_ERROR,
764
+ grpc_slice_from_static_string(strerror(err))),
765
+ GRPC_ERROR_STR_SYSCALL, grpc_slice_from_static_string(call_name));
586
766
  }
587
767
 
588
768
  #ifdef GPR_WINDOWS
@@ -591,10 +771,13 @@ grpc_error *grpc_wsa_error(const char *file, int line, int err,
591
771
  char *utf8_message = gpr_format_message(err);
592
772
  grpc_error *error = grpc_error_set_str(
593
773
  grpc_error_set_str(
594
- grpc_error_set_int(grpc_error_create(file, line, "OS Error", NULL, 0),
595
- GRPC_ERROR_INT_WSA_ERROR, err),
596
- GRPC_ERROR_STR_OS_ERROR, utf8_message),
597
- GRPC_ERROR_STR_SYSCALL, call_name);
774
+ grpc_error_set_int(
775
+ grpc_error_create(grpc_slice_from_static_string(file), line,
776
+ grpc_slice_from_static_string("OS Error"), NULL,
777
+ 0),
778
+ GRPC_ERROR_INT_WSA_ERROR, err),
779
+ GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_copied_string(utf8_message)),
780
+ GRPC_ERROR_STR_SYSCALL, grpc_slice_from_static_string(call_name));
598
781
  gpr_free(utf8_message);
599
782
  return error;
600
783
  }