grpc 1.0.1 → 1.1.2

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 (705) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +3696 -867
  3. data/etc/roots.pem +39 -111
  4. data/include/grpc/byte_buffer.h +64 -1
  5. data/include/grpc/census.h +40 -96
  6. data/include/grpc/compression.h +2 -1
  7. data/include/grpc/grpc.h +42 -7
  8. data/include/grpc/grpc_posix.h +8 -5
  9. data/include/grpc/impl/codegen/atm.h +3 -0
  10. data/include/grpc/impl/codegen/atm_gcc_atomic.h +2 -0
  11. data/include/grpc/impl/codegen/atm_gcc_sync.h +8 -0
  12. data/include/grpc/impl/codegen/atm_windows.h +4 -0
  13. data/include/grpc/impl/codegen/byte_buffer_reader.h +4 -4
  14. data/include/grpc/impl/codegen/compression_types.h +1 -1
  15. data/include/grpc/impl/codegen/connectivity_state.h +2 -0
  16. data/include/grpc/impl/codegen/exec_ctx_fwd.h +41 -0
  17. data/include/grpc/impl/codegen/gpr_slice.h +84 -0
  18. data/include/grpc/impl/codegen/{alloc.h → gpr_types.h} +30 -29
  19. data/include/grpc/impl/codegen/grpc_types.h +91 -9
  20. data/include/grpc/impl/codegen/port_platform.h +25 -92
  21. data/include/grpc/impl/codegen/slice.h +54 -97
  22. data/include/grpc/impl/codegen/sync.h +0 -253
  23. data/include/grpc/module.modulemap +0 -2
  24. data/include/grpc/slice.h +132 -0
  25. data/include/grpc/{impl/codegen/slice_buffer.h → slice_buffer.h} +22 -39
  26. data/include/grpc/support/alloc.h +40 -1
  27. data/include/grpc/support/log.h +80 -1
  28. data/include/grpc/support/log_windows.h +2 -0
  29. data/include/grpc/support/string_util.h +1 -1
  30. data/include/grpc/support/sync.h +252 -0
  31. data/include/grpc/support/time.h +67 -1
  32. data/src/boringssl/err_data.c +639 -627
  33. data/src/core/ext/census/base_resources.c +71 -0
  34. data/src/core/ext/census/base_resources.h +39 -0
  35. data/src/core/ext/census/gen/census.pb.c +26 -29
  36. data/src/core/ext/census/gen/census.pb.h +68 -67
  37. data/src/core/ext/census/gen/trace_context.pb.c +81 -0
  38. data/src/core/ext/census/gen/trace_context.pb.h +99 -0
  39. data/src/core/ext/census/grpc_filter.c +22 -16
  40. data/src/core/ext/census/grpc_plugin.c +2 -1
  41. data/src/core/ext/census/initialize.c +16 -4
  42. data/src/core/ext/census/mlog.h +1 -1
  43. data/src/core/ext/census/placeholders.c +0 -45
  44. data/src/core/ext/census/resource.c +312 -0
  45. data/src/core/ext/census/resource.h +63 -0
  46. data/src/core/ext/census/trace_context.c +86 -0
  47. data/src/core/ext/census/trace_context.h +68 -0
  48. data/src/core/ext/census/tracing.c +8 -2
  49. data/src/core/ext/{client_config → client_channel}/channel_connectivity.c +8 -4
  50. data/src/core/ext/client_channel/client_channel.c +1218 -0
  51. data/src/core/ext/{client_config → client_channel}/client_channel.h +8 -11
  52. data/src/core/ext/{client_config → client_channel}/client_channel_factory.c +33 -3
  53. data/src/core/ext/{client_config → client_channel}/client_channel_factory.h +15 -8
  54. data/src/core/ext/{client_config/client_config_plugin.c → client_channel/client_channel_plugin.c} +16 -15
  55. data/src/core/ext/{client_config → client_channel}/connector.c +1 -1
  56. data/src/core/ext/{client_config → client_channel}/connector.h +5 -8
  57. data/{include/grpc/support/slice_buffer.h → src/core/ext/client_channel/default_initial_connect_string.c} +4 -5
  58. data/src/core/ext/client_channel/http_connect_handshaker.c +399 -0
  59. data/src/core/ext/client_channel/http_connect_handshaker.h +52 -0
  60. data/src/core/ext/{client_config → client_channel}/initial_connect_string.c +6 -7
  61. data/src/core/ext/{client_config → client_channel}/initial_connect_string.h +10 -10
  62. data/src/core/ext/{client_config → client_channel}/lb_policy.c +11 -11
  63. data/src/core/ext/{client_config → client_channel}/lb_policy.h +68 -27
  64. data/src/core/ext/client_channel/lb_policy_factory.c +163 -0
  65. data/src/core/ext/{client_config → client_channel}/lb_policy_factory.h +64 -9
  66. data/src/core/ext/{client_config → client_channel}/lb_policy_registry.c +6 -4
  67. data/src/core/ext/{client_config → client_channel}/lb_policy_registry.h +4 -4
  68. data/src/core/ext/{client_config → client_channel}/parse_address.c +21 -14
  69. data/src/core/ext/{client_config → client_channel}/parse_address.h +8 -10
  70. data/src/core/ext/{client_config → client_channel}/resolver.c +3 -4
  71. data/src/core/ext/{client_config → client_channel}/resolver.h +11 -15
  72. data/src/core/ext/{client_config → client_channel}/resolver_factory.c +4 -3
  73. data/src/core/ext/{client_config → client_channel}/resolver_factory.h +13 -11
  74. data/src/core/ext/{client_config → client_channel}/resolver_registry.c +54 -34
  75. data/src/core/ext/{client_config → client_channel}/resolver_registry.h +21 -8
  76. data/src/core/ext/{client_config → client_channel}/subchannel.c +208 -119
  77. data/src/core/ext/{client_config → client_channel}/subchannel.h +21 -11
  78. data/src/core/ext/{client_config → client_channel}/subchannel_index.c +6 -17
  79. data/src/core/ext/{client_config → client_channel}/subchannel_index.h +7 -7
  80. data/src/core/ext/{client_config → client_channel}/uri_parser.c +21 -28
  81. data/src/core/ext/{client_config → client_channel}/uri_parser.h +3 -3
  82. data/src/core/ext/lb_policy/grpclb/grpclb.c +1406 -0
  83. data/src/core/ext/lb_policy/grpclb/grpclb.h +44 -0
  84. data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +117 -37
  85. data/src/core/ext/lb_policy/grpclb/load_balancer_api.h +31 -12
  86. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +6 -36
  87. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +22 -42
  88. data/src/core/ext/lb_policy/pick_first/pick_first.c +64 -46
  89. data/src/core/ext/lb_policy/round_robin/round_robin.c +324 -160
  90. data/src/core/ext/load_reporting/load_reporting.c +7 -56
  91. data/src/core/ext/load_reporting/load_reporting.h +41 -28
  92. data/src/core/ext/load_reporting/load_reporting_filter.c +132 -42
  93. data/src/core/ext/load_reporting/load_reporting_filter.h +1 -0
  94. data/src/core/ext/resolver/dns/native/dns_resolver.c +88 -80
  95. data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +57 -102
  96. data/src/core/ext/transport/chttp2/alpn/alpn.c +1 -1
  97. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +253 -0
  98. data/src/core/{lib/iomgr/ev_poll_and_epoll_posix.h → ext/transport/chttp2/client/chttp2_connector.h} +5 -5
  99. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +31 -160
  100. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +5 -5
  101. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +44 -243
  102. data/src/core/ext/transport/chttp2/server/chttp2_server.c +342 -0
  103. data/src/core/ext/transport/chttp2/server/chttp2_server.h +47 -0
  104. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +11 -124
  105. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +20 -9
  106. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +28 -236
  107. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +31 -27
  108. data/src/core/ext/transport/chttp2/transport/bin_decoder.h +5 -4
  109. data/src/core/ext/transport/chttp2/transport/bin_encoder.c +25 -22
  110. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +8 -7
  111. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
  112. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +1345 -1521
  113. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -1
  114. data/src/core/ext/transport/chttp2/transport/frame.h +3 -5
  115. data/src/core/ext/transport/chttp2/transport/frame_data.c +50 -47
  116. data/src/core/ext/transport/chttp2/transport/frame_data.h +8 -9
  117. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +19 -21
  118. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +9 -8
  119. data/src/core/ext/transport/chttp2/transport/frame_ping.c +13 -12
  120. data/src/core/ext/transport/chttp2/transport/frame_ping.h +6 -6
  121. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +31 -19
  122. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +8 -7
  123. data/src/core/ext/transport/chttp2/transport/frame_settings.c +22 -25
  124. data/src/core/ext/transport/chttp2/transport/frame_settings.h +9 -8
  125. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +26 -18
  126. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +5 -6
  127. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +68 -58
  128. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +8 -5
  129. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +327 -214
  130. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +14 -9
  131. data/src/core/ext/transport/chttp2/transport/hpack_table.c +24 -19
  132. data/src/core/ext/transport/chttp2/transport/hpack_table.h +9 -6
  133. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +2 -2
  134. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +1 -1
  135. data/src/core/ext/transport/chttp2/transport/internal.h +284 -436
  136. data/src/core/ext/transport/chttp2/transport/parsing.c +355 -590
  137. data/src/core/ext/transport/chttp2/transport/stream_lists.c +36 -309
  138. data/src/core/ext/transport/chttp2/transport/stream_map.c +13 -34
  139. data/src/core/ext/transport/chttp2/transport/stream_map.h +3 -4
  140. data/src/core/ext/transport/chttp2/transport/writing.c +174 -286
  141. data/src/core/lib/channel/channel_args.c +70 -13
  142. data/src/core/lib/channel/channel_args.h +28 -2
  143. data/src/core/lib/channel/channel_stack.c +77 -28
  144. data/src/core/lib/channel/channel_stack.h +61 -23
  145. data/src/core/lib/channel/channel_stack_builder.c +33 -25
  146. data/src/core/lib/channel/channel_stack_builder.h +17 -8
  147. data/src/core/lib/channel/compress_filter.c +52 -36
  148. data/src/core/lib/channel/connected_channel.c +20 -12
  149. data/src/core/lib/channel/connected_channel.h +2 -1
  150. data/src/core/lib/channel/context.h +13 -1
  151. data/src/core/lib/channel/deadline_filter.c +344 -0
  152. data/src/core/lib/channel/deadline_filter.h +99 -0
  153. data/src/core/lib/channel/handshaker.c +240 -0
  154. data/src/core/lib/channel/handshaker.h +164 -0
  155. data/src/core/lib/{security/credentials/google_default/credentials_windows.c → channel/handshaker_factory.c} +16 -23
  156. data/src/core/lib/channel/handshaker_factory.h +66 -0
  157. data/src/core/lib/channel/handshaker_registry.c +113 -0
  158. data/src/core/{ext/client_config/client_config.h → lib/channel/handshaker_registry.h} +26 -16
  159. data/src/core/lib/channel/http_client_filter.c +248 -46
  160. data/src/core/lib/channel/http_client_filter.h +3 -0
  161. data/src/core/lib/channel/http_server_filter.c +136 -24
  162. data/src/core/lib/channel/message_size_filter.c +261 -0
  163. data/src/core/lib/channel/message_size_filter.h +39 -0
  164. data/src/core/lib/compression/message_compress.c +43 -37
  165. data/src/core/lib/compression/message_compress.h +7 -5
  166. data/src/core/lib/http/format_request.c +26 -11
  167. data/src/core/lib/http/format_request.h +7 -5
  168. data/src/core/lib/http/httpcli.c +45 -27
  169. data/src/core/lib/http/httpcli.h +4 -4
  170. data/src/core/lib/http/httpcli_security_connector.c +56 -46
  171. data/src/core/lib/http/parser.c +17 -14
  172. data/src/core/lib/http/parser.h +4 -2
  173. data/src/core/lib/iomgr/closure.c +49 -7
  174. data/src/core/lib/iomgr/closure.h +56 -14
  175. data/src/core/lib/iomgr/combiner.c +422 -0
  176. data/src/core/lib/iomgr/combiner.h +64 -0
  177. data/src/core/lib/iomgr/endpoint.c +8 -2
  178. data/src/core/lib/iomgr/endpoint.h +17 -7
  179. data/src/core/lib/iomgr/endpoint_pair.h +3 -2
  180. data/src/core/lib/iomgr/endpoint_pair_posix.c +9 -8
  181. data/src/core/{ext/client_config/lb_policy_factory.c → lib/iomgr/endpoint_pair_uv.c} +18 -13
  182. data/src/core/lib/iomgr/endpoint_pair_windows.c +7 -6
  183. data/src/core/lib/iomgr/error.c +72 -6
  184. data/src/core/lib/iomgr/error.h +30 -3
  185. data/src/core/lib/iomgr/ev_epoll_linux.c +500 -382
  186. data/src/core/lib/iomgr/ev_epoll_linux.h +3 -2
  187. data/src/core/lib/iomgr/ev_poll_posix.c +317 -30
  188. data/src/core/lib/iomgr/ev_poll_posix.h +1 -0
  189. data/src/core/lib/iomgr/ev_posix.c +26 -5
  190. data/src/core/lib/iomgr/ev_posix.h +12 -1
  191. data/src/core/lib/iomgr/exec_ctx.c +27 -94
  192. data/src/core/lib/iomgr/exec_ctx.h +19 -22
  193. data/src/core/lib/iomgr/executor.c +29 -8
  194. data/src/core/lib/iomgr/executor.h +2 -4
  195. data/src/core/lib/iomgr/iocp_windows.c +3 -4
  196. data/src/core/lib/iomgr/iomgr.c +14 -10
  197. data/src/core/lib/iomgr/iomgr.h +6 -2
  198. data/src/core/lib/iomgr/iomgr_posix.c +2 -2
  199. data/src/core/lib/iomgr/iomgr_uv.c +49 -0
  200. data/src/core/lib/iomgr/iomgr_windows.c +2 -2
  201. data/src/core/lib/iomgr/load_file.c +3 -3
  202. data/src/core/lib/iomgr/load_file.h +2 -2
  203. data/src/core/lib/iomgr/network_status_tracker.c +1 -1
  204. data/src/core/lib/iomgr/pollset_set_uv.c +62 -0
  205. data/src/core/lib/iomgr/pollset_set_windows.c +3 -3
  206. data/src/core/lib/iomgr/pollset_uv.c +142 -0
  207. data/src/core/lib/iomgr/pollset_uv.h +42 -0
  208. data/src/core/lib/iomgr/pollset_windows.c +5 -6
  209. data/src/core/lib/iomgr/port.h +129 -0
  210. data/src/core/lib/iomgr/resolve_address.h +2 -1
  211. data/src/core/lib/iomgr/resolve_address_posix.c +14 -13
  212. data/src/core/lib/iomgr/resolve_address_uv.c +233 -0
  213. data/src/core/lib/iomgr/resolve_address_windows.c +14 -12
  214. data/src/core/lib/iomgr/resource_quota.c +832 -0
  215. data/src/core/lib/iomgr/resource_quota.h +159 -0
  216. data/src/core/lib/iomgr/sockaddr.h +10 -2
  217. data/src/core/lib/iomgr/sockaddr_utils.c +63 -36
  218. data/src/core/lib/iomgr/sockaddr_utils.h +14 -14
  219. data/src/core/lib/iomgr/socket_mutator.c +98 -0
  220. data/src/core/lib/iomgr/socket_mutator.h +80 -0
  221. data/src/core/lib/iomgr/socket_utils.h +42 -0
  222. data/src/core/lib/iomgr/socket_utils_common_posix.c +28 -13
  223. data/src/core/lib/iomgr/socket_utils_linux.c +11 -5
  224. data/src/core/lib/iomgr/socket_utils_posix.c +10 -7
  225. data/src/core/lib/iomgr/socket_utils_posix.h +11 -4
  226. data/src/core/lib/iomgr/socket_utils_uv.c +49 -0
  227. data/src/core/lib/iomgr/socket_utils_windows.c +52 -0
  228. data/src/core/lib/iomgr/socket_windows.c +14 -6
  229. data/src/core/lib/iomgr/socket_windows.h +1 -0
  230. data/src/core/lib/iomgr/tcp_client.h +8 -2
  231. data/src/core/lib/iomgr/tcp_client_posix.c +131 -82
  232. data/src/core/lib/iomgr/tcp_client_posix.h +45 -0
  233. data/src/core/lib/iomgr/tcp_client_uv.c +190 -0
  234. data/src/core/lib/iomgr/tcp_client_windows.c +54 -30
  235. data/src/core/lib/iomgr/tcp_posix.c +135 -56
  236. data/src/core/lib/iomgr/tcp_posix.h +2 -2
  237. data/src/core/lib/iomgr/tcp_server.h +14 -6
  238. data/src/core/lib/iomgr/tcp_server_posix.c +154 -118
  239. data/src/core/lib/iomgr/tcp_server_uv.c +388 -0
  240. data/src/core/lib/iomgr/tcp_server_windows.c +127 -100
  241. data/src/core/lib/iomgr/tcp_uv.c +367 -0
  242. data/src/core/lib/iomgr/tcp_uv.h +59 -0
  243. data/src/core/lib/iomgr/tcp_windows.c +65 -48
  244. data/src/core/lib/iomgr/tcp_windows.h +3 -1
  245. data/src/core/lib/iomgr/timer.h +21 -21
  246. data/src/core/lib/iomgr/{timer.c → timer_generic.c} +15 -10
  247. data/src/core/lib/iomgr/timer_generic.h +49 -0
  248. data/src/core/lib/iomgr/timer_heap.c +6 -0
  249. data/src/core/lib/iomgr/timer_uv.c +99 -0
  250. data/src/core/lib/iomgr/timer_uv.h +47 -0
  251. data/src/core/lib/iomgr/udp_server.c +116 -98
  252. data/src/core/lib/iomgr/udp_server.h +5 -3
  253. data/src/core/lib/iomgr/unix_sockets_posix.c +14 -6
  254. data/src/core/lib/iomgr/unix_sockets_posix.h +6 -5
  255. data/src/core/lib/iomgr/unix_sockets_posix_noop.c +4 -4
  256. data/src/core/lib/iomgr/wakeup_fd_cv.c +118 -0
  257. data/src/core/lib/iomgr/wakeup_fd_cv.h +80 -0
  258. data/src/core/lib/iomgr/wakeup_fd_eventfd.c +3 -3
  259. data/src/core/lib/iomgr/wakeup_fd_nospecial.c +3 -3
  260. data/src/core/lib/iomgr/wakeup_fd_pipe.c +12 -6
  261. data/src/core/lib/iomgr/wakeup_fd_posix.c +34 -5
  262. data/src/core/lib/iomgr/wakeup_fd_posix.h +5 -0
  263. data/src/core/lib/iomgr/workqueue.h +12 -20
  264. data/src/core/{ext/client_config/client_config.c → lib/iomgr/workqueue_uv.c} +24 -33
  265. data/{include/grpc/support/slice.h → src/core/lib/iomgr/workqueue_uv.h} +4 -6
  266. data/src/core/lib/iomgr/workqueue_windows.c +9 -8
  267. data/src/core/lib/json/json.c +3 -3
  268. data/src/core/lib/json/json.h +11 -11
  269. data/src/core/lib/json/json_reader.c +9 -5
  270. data/src/core/lib/profiling/basic_timers.c +10 -1
  271. data/src/core/lib/profiling/timers.h +2 -0
  272. data/src/core/lib/security/context/security_context.c +13 -3
  273. data/src/core/lib/security/context/security_context.h +20 -0
  274. data/src/core/lib/security/credentials/composite/composite_credentials.c +28 -14
  275. data/src/core/lib/security/credentials/composite/composite_credentials.h +2 -2
  276. data/src/core/lib/security/credentials/credentials.c +48 -19
  277. data/src/core/lib/security/credentials/credentials.h +36 -19
  278. data/src/core/lib/security/credentials/credentials_metadata.c +11 -8
  279. data/src/core/lib/security/credentials/fake/fake_credentials.c +15 -11
  280. data/src/core/lib/security/credentials/google_default/{credentials_posix.c → credentials_generic.c} +7 -14
  281. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +33 -21
  282. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +14 -0
  283. data/src/core/lib/security/credentials/iam/iam_credentials.c +3 -2
  284. data/src/core/lib/security/credentials/jwt/json_token.c +1 -0
  285. data/src/core/lib/security/credentials/jwt/json_token.h +1 -1
  286. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +54 -19
  287. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +2 -1
  288. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +129 -79
  289. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +9 -6
  290. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +63 -28
  291. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +1 -1
  292. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +32 -11
  293. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +13 -9
  294. data/src/core/lib/security/transport/client_auth_filter.c +33 -27
  295. data/src/core/lib/security/transport/secure_endpoint.c +93 -68
  296. data/src/core/lib/security/transport/secure_endpoint.h +2 -2
  297. data/src/core/lib/security/transport/security_connector.c +133 -168
  298. data/src/core/lib/security/transport/security_connector.h +31 -46
  299. data/src/core/lib/security/transport/security_handshaker.c +501 -0
  300. data/src/core/lib/security/transport/{handshake.h → security_handshaker.h} +10 -10
  301. data/src/core/lib/security/transport/server_auth_filter.c +50 -38
  302. data/src/core/lib/security/util/b64.c +11 -8
  303. data/src/core/lib/security/util/b64.h +5 -4
  304. data/src/core/lib/slice/percent_encoding.c +182 -0
  305. data/src/core/lib/slice/percent_encoding.h +78 -0
  306. data/src/core/lib/{support → slice}/slice.c +81 -50
  307. data/src/core/lib/{support → slice}/slice_buffer.c +78 -60
  308. data/src/core/lib/slice/slice_internal.h +49 -0
  309. data/src/core/lib/slice/slice_string_helpers.c +90 -0
  310. data/src/core/lib/{iomgr/workqueue_posix.h → slice/slice_string_helpers.h} +18 -18
  311. data/src/core/lib/support/backoff.c +24 -13
  312. data/src/core/lib/support/backoff.h +5 -2
  313. data/src/core/lib/support/env.h +0 -2
  314. data/src/core/lib/support/log.c +5 -4
  315. data/src/core/lib/support/log_linux.c +0 -1
  316. data/src/core/lib/support/log_posix.c +1 -1
  317. data/src/core/lib/support/mpscq.c +83 -0
  318. data/src/core/lib/support/mpscq.h +65 -0
  319. data/src/core/lib/support/string.c +58 -49
  320. data/src/core/lib/support/string.h +11 -8
  321. data/src/core/lib/support/subprocess_posix.c +5 -2
  322. data/src/core/lib/support/thd.c +1 -1
  323. data/src/core/lib/support/time.c +43 -79
  324. data/src/core/lib/support/time_posix.c +1 -1
  325. data/src/core/lib/support/tmpfile.h +0 -2
  326. data/src/core/lib/surface/alarm.c +4 -1
  327. data/src/core/lib/surface/byte_buffer.c +17 -11
  328. data/src/core/lib/surface/byte_buffer_reader.c +23 -15
  329. data/src/core/lib/surface/call.c +294 -276
  330. data/src/core/lib/surface/call.h +24 -9
  331. data/src/core/lib/surface/call_log_batch.c +5 -3
  332. data/src/core/lib/surface/channel.c +127 -111
  333. data/src/core/lib/surface/channel.h +14 -5
  334. data/src/core/lib/surface/channel_init.c +1 -1
  335. data/src/core/lib/surface/channel_init.h +10 -1
  336. data/src/core/lib/surface/channel_ping.c +7 -6
  337. data/src/core/lib/surface/completion_queue.c +154 -18
  338. data/src/core/lib/surface/completion_queue.h +5 -0
  339. data/src/core/lib/surface/init.c +40 -6
  340. data/src/core/lib/surface/init.h +1 -0
  341. data/src/core/lib/surface/init_secure.c +5 -2
  342. data/src/core/lib/surface/lame_client.c +28 -18
  343. data/src/core/lib/surface/server.c +134 -87
  344. data/src/core/lib/surface/server.h +8 -0
  345. data/src/core/lib/surface/validate_metadata.c +1 -1
  346. data/src/core/lib/surface/version.c +3 -1
  347. data/src/core/lib/transport/byte_stream.c +7 -4
  348. data/src/core/lib/transport/byte_stream.h +6 -10
  349. data/src/core/lib/transport/connectivity_state.c +21 -12
  350. data/src/core/lib/transport/connectivity_state.h +4 -1
  351. data/src/core/lib/transport/mdstr_hash_table.c +118 -0
  352. data/src/core/lib/transport/mdstr_hash_table.h +77 -0
  353. data/src/core/lib/transport/metadata.c +83 -60
  354. data/src/core/lib/transport/metadata.h +41 -23
  355. data/src/core/lib/transport/metadata_batch.c +17 -11
  356. data/src/core/lib/transport/metadata_batch.h +20 -6
  357. data/src/core/lib/transport/pid_controller.c +57 -0
  358. data/src/core/lib/transport/pid_controller.h +64 -0
  359. data/src/core/lib/transport/service_config.c +251 -0
  360. data/src/core/lib/transport/service_config.h +71 -0
  361. data/src/core/lib/transport/static_metadata.c +18 -16
  362. data/src/core/lib/transport/static_metadata.h +113 -107
  363. data/src/core/{ext/transport/chttp2 → lib}/transport/timeout_encoding.c +3 -3
  364. data/src/core/{ext/transport/chttp2 → lib}/transport/timeout_encoding.h +7 -7
  365. data/src/core/lib/transport/transport.c +84 -23
  366. data/src/core/lib/transport/transport.h +53 -8
  367. data/src/core/lib/transport/transport_impl.h +3 -0
  368. data/src/core/lib/transport/transport_op_string.c +92 -20
  369. data/src/core/lib/tsi/ssl_transport_security.c +3 -1
  370. data/src/core/plugin_registry/grpc_plugin_registry.c +8 -4
  371. data/src/ruby/ext/grpc/extconf.rb +0 -1
  372. data/src/ruby/ext/grpc/rb_byte_buffer.c +8 -7
  373. data/src/ruby/ext/grpc/rb_call.c +15 -5
  374. data/src/ruby/ext/grpc/rb_channel.c +1 -1
  375. data/src/ruby/ext/grpc/rb_compression_options.c +466 -0
  376. data/src/{core/ext/client_config/default_initial_connect_string.c → ruby/ext/grpc/rb_compression_options.h} +10 -5
  377. data/src/ruby/ext/grpc/rb_grpc.c +3 -1
  378. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +198 -190
  379. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +306 -294
  380. data/src/ruby/ext/grpc/rb_server.c +18 -12
  381. data/src/ruby/lib/grpc/errors.rb +154 -2
  382. data/src/ruby/lib/grpc/generic/active_call.rb +144 -63
  383. data/src/ruby/lib/grpc/generic/bidi_call.rb +18 -2
  384. data/src/ruby/lib/grpc/generic/client_stub.rb +7 -5
  385. data/src/ruby/lib/grpc/generic/rpc_desc.rb +39 -13
  386. data/src/ruby/lib/grpc/generic/rpc_server.rb +51 -24
  387. data/src/ruby/lib/grpc/generic/service.rb +3 -2
  388. data/src/ruby/lib/grpc/version.rb +1 -1
  389. data/src/ruby/pb/grpc/health/checker.rb +3 -1
  390. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +7 -0
  391. data/src/ruby/pb/test/client.rb +307 -7
  392. data/src/ruby/pb/test/server.rb +26 -1
  393. data/src/ruby/spec/compression_options_spec.rb +164 -0
  394. data/src/ruby/spec/error_sanity_spec.rb +64 -0
  395. data/src/ruby/spec/generic/active_call_spec.rb +290 -12
  396. data/src/ruby/spec/generic/client_stub_spec.rb +91 -41
  397. data/src/ruby/spec/generic/rpc_desc_spec.rb +36 -16
  398. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +22 -28
  399. data/src/ruby/spec/generic/rpc_server_spec.rb +6 -6
  400. data/src/ruby/spec/pb/health/checker_spec.rb +27 -19
  401. data/src/ruby/spec/spec_helper.rb +2 -0
  402. data/third_party/boringssl/crypto/aes/aes.c +12 -12
  403. data/third_party/boringssl/crypto/aes/mode_wrappers.c +6 -2
  404. data/third_party/boringssl/crypto/asn1/a_d2i_fp.c +28 -13
  405. data/third_party/boringssl/crypto/asn1/a_gentm.c +2 -0
  406. data/third_party/boringssl/crypto/asn1/a_object.c +7 -3
  407. data/third_party/boringssl/crypto/asn1/a_strnid.c +1 -0
  408. data/third_party/boringssl/crypto/asn1/a_time.c +0 -11
  409. data/third_party/boringssl/crypto/asn1/a_type.c +0 -2
  410. data/third_party/boringssl/crypto/asn1/a_utctm.c +1 -30
  411. data/third_party/boringssl/crypto/asn1/asn1_lib.c +56 -76
  412. data/third_party/boringssl/crypto/asn1/asn1_locl.h +0 -10
  413. data/third_party/boringssl/crypto/asn1/asn1_par.c +0 -322
  414. data/third_party/boringssl/crypto/asn1/f_enum.c +1 -108
  415. data/third_party/boringssl/crypto/asn1/f_int.c +1 -106
  416. data/third_party/boringssl/crypto/asn1/f_string.c +1 -106
  417. data/third_party/boringssl/crypto/asn1/tasn_dec.c +10 -14
  418. data/third_party/boringssl/crypto/asn1/tasn_enc.c +17 -11
  419. data/third_party/boringssl/crypto/asn1/tasn_typ.c +29 -42
  420. data/third_party/boringssl/crypto/asn1/tasn_utl.c +1 -1
  421. data/third_party/boringssl/crypto/base64/base64.c +249 -285
  422. data/third_party/boringssl/crypto/bio/bio.c +13 -23
  423. data/third_party/boringssl/crypto/bio/bio_mem.c +3 -2
  424. data/third_party/boringssl/crypto/bio/connect.c +12 -3
  425. data/third_party/boringssl/crypto/bio/fd.c +22 -15
  426. data/third_party/boringssl/crypto/bio/file.c +2 -38
  427. data/third_party/boringssl/crypto/bio/hexdump.c +1 -2
  428. data/third_party/boringssl/crypto/bio/internal.h +3 -0
  429. data/third_party/boringssl/crypto/bio/pair.c +1 -1
  430. data/third_party/boringssl/crypto/bio/socket.c +10 -2
  431. data/third_party/boringssl/crypto/bio/socket_helper.c +2 -2
  432. data/third_party/boringssl/crypto/bn/asm/x86_64-gcc.c +0 -8
  433. data/third_party/boringssl/crypto/bn/bn.c +38 -0
  434. data/third_party/boringssl/crypto/bn/cmp.c +25 -0
  435. data/third_party/boringssl/crypto/bn/convert.c +73 -76
  436. data/third_party/boringssl/crypto/bn/div.c +136 -70
  437. data/third_party/boringssl/crypto/bn/exponentiation.c +86 -381
  438. data/third_party/boringssl/crypto/bn/gcd.c +213 -296
  439. data/third_party/boringssl/crypto/bn/generic.c +0 -80
  440. data/third_party/boringssl/crypto/bn/internal.h +15 -3
  441. data/third_party/boringssl/crypto/bn/montgomery.c +57 -207
  442. data/third_party/boringssl/crypto/bn/montgomery_inv.c +160 -0
  443. data/third_party/boringssl/crypto/bn/mul.c +2 -1
  444. data/third_party/boringssl/crypto/bn/prime.c +24 -8
  445. data/third_party/boringssl/crypto/bn/random.c +47 -33
  446. data/third_party/boringssl/crypto/bn/sqrt.c +4 -5
  447. data/third_party/boringssl/crypto/buf/buf.c +25 -21
  448. data/third_party/boringssl/crypto/bytestring/ber.c +1 -0
  449. data/third_party/boringssl/crypto/bytestring/cbb.c +50 -22
  450. data/third_party/boringssl/crypto/bytestring/cbs.c +28 -4
  451. data/third_party/boringssl/crypto/chacha/{chacha_generic.c → chacha.c} +56 -29
  452. data/third_party/boringssl/crypto/cipher/aead.c +11 -22
  453. data/third_party/boringssl/crypto/cipher/cipher.c +2 -2
  454. data/third_party/boringssl/crypto/cipher/e_aes.c +53 -103
  455. data/third_party/boringssl/crypto/cipher/e_chacha20poly1305.c +2 -8
  456. data/third_party/boringssl/crypto/cipher/e_des.c +3 -5
  457. data/third_party/boringssl/crypto/cipher/e_null.c +1 -1
  458. data/third_party/boringssl/crypto/cipher/e_rc2.c +1 -1
  459. data/third_party/boringssl/crypto/cipher/e_rc4.c +1 -1
  460. data/third_party/boringssl/crypto/cipher/e_ssl3.c +3 -63
  461. data/third_party/boringssl/crypto/cipher/e_tls.c +12 -83
  462. data/third_party/boringssl/crypto/cipher/internal.h +8 -10
  463. data/third_party/boringssl/crypto/cipher/tls_cbc.c +69 -40
  464. data/third_party/boringssl/crypto/conf/conf.c +2 -1
  465. data/third_party/boringssl/crypto/cpu-aarch64-linux.c +61 -0
  466. data/third_party/boringssl/crypto/cpu-arm-linux.c +360 -0
  467. data/third_party/boringssl/crypto/cpu-arm.c +0 -161
  468. data/third_party/boringssl/crypto/cpu-intel.c +5 -3
  469. data/third_party/boringssl/{ssl/test/scoped_types.h → crypto/cpu-ppc64le.c} +21 -9
  470. data/third_party/boringssl/crypto/crypto.c +29 -7
  471. data/third_party/boringssl/crypto/curve25519/curve25519.c +284 -242
  472. data/third_party/boringssl/crypto/curve25519/internal.h +64 -0
  473. data/third_party/boringssl/crypto/curve25519/spake25519.c +464 -0
  474. data/third_party/boringssl/crypto/curve25519/x25519-x86_64.c +21 -0
  475. data/third_party/boringssl/crypto/dh/check.c +22 -6
  476. data/third_party/boringssl/crypto/dh/dh.c +45 -21
  477. data/third_party/boringssl/crypto/dh/dh_asn1.c +96 -20
  478. data/third_party/boringssl/crypto/dh/params.c +30 -78
  479. data/third_party/boringssl/crypto/digest/digest.c +3 -3
  480. data/third_party/boringssl/crypto/dsa/dsa.c +59 -29
  481. data/third_party/boringssl/crypto/dsa/dsa_asn1.c +4 -0
  482. data/third_party/boringssl/crypto/ec/ec.c +84 -140
  483. data/third_party/boringssl/crypto/ec/ec_asn1.c +82 -52
  484. data/third_party/boringssl/crypto/ec/ec_key.c +15 -15
  485. data/third_party/boringssl/crypto/ec/ec_montgomery.c +87 -50
  486. data/third_party/boringssl/crypto/ec/internal.h +12 -36
  487. data/third_party/boringssl/crypto/ec/oct.c +11 -11
  488. data/third_party/boringssl/crypto/ec/p224-64.c +59 -116
  489. data/third_party/boringssl/crypto/ec/p256-64.c +88 -163
  490. data/third_party/boringssl/crypto/ec/p256-x86_64.c +46 -58
  491. data/third_party/boringssl/crypto/ec/simple.c +81 -201
  492. data/third_party/boringssl/crypto/ec/util-64.c +0 -74
  493. data/third_party/boringssl/crypto/ecdh/ecdh.c +7 -1
  494. data/third_party/boringssl/crypto/ecdsa/ecdsa.c +28 -46
  495. data/third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c +1 -0
  496. data/third_party/boringssl/crypto/engine/engine.c +1 -1
  497. data/third_party/boringssl/crypto/err/err.c +3 -3
  498. data/third_party/boringssl/crypto/evp/evp.c +14 -59
  499. data/third_party/boringssl/crypto/evp/evp_asn1.c +144 -87
  500. data/third_party/boringssl/crypto/evp/evp_ctx.c +7 -7
  501. data/third_party/boringssl/crypto/evp/internal.h +4 -46
  502. data/third_party/boringssl/crypto/evp/p_dsa_asn1.c +8 -157
  503. data/third_party/boringssl/crypto/evp/p_ec.c +1 -1
  504. data/third_party/boringssl/crypto/evp/p_ec_asn1.c +22 -170
  505. data/third_party/boringssl/crypto/evp/p_rsa.c +1 -1
  506. data/third_party/boringssl/crypto/evp/p_rsa_asn1.c +10 -548
  507. data/third_party/boringssl/crypto/evp/print.c +520 -0
  508. data/third_party/boringssl/crypto/ex_data.c +4 -6
  509. data/third_party/boringssl/crypto/hkdf/hkdf.c +38 -17
  510. data/third_party/boringssl/crypto/hmac/hmac.c +6 -6
  511. data/third_party/boringssl/crypto/internal.h +57 -77
  512. data/third_party/boringssl/crypto/lhash/lhash.c +6 -10
  513. data/third_party/boringssl/crypto/md4/md4.c +9 -0
  514. data/third_party/boringssl/crypto/mem.c +19 -19
  515. data/third_party/boringssl/crypto/modes/cfb.c +5 -6
  516. data/third_party/boringssl/crypto/modes/ctr.c +10 -18
  517. data/third_party/boringssl/crypto/modes/gcm.c +100 -66
  518. data/third_party/boringssl/crypto/modes/internal.h +15 -27
  519. data/third_party/boringssl/crypto/modes/ofb.c +9 -22
  520. data/third_party/boringssl/crypto/newhope/error_correction.c +131 -0
  521. data/third_party/boringssl/crypto/newhope/internal.h +71 -0
  522. data/third_party/boringssl/crypto/newhope/newhope.c +174 -0
  523. data/third_party/boringssl/crypto/newhope/ntt.c +148 -0
  524. data/third_party/boringssl/crypto/newhope/poly.c +183 -0
  525. data/third_party/boringssl/crypto/newhope/precomp.c +306 -0
  526. data/third_party/boringssl/crypto/newhope/reduce.c +42 -0
  527. data/third_party/boringssl/crypto/obj/obj.c +111 -135
  528. data/third_party/boringssl/crypto/obj/obj_dat.h +4 -10
  529. data/third_party/boringssl/crypto/pem/pem_lib.c +6 -43
  530. data/third_party/boringssl/crypto/pem/pem_pkey.c +10 -19
  531. data/third_party/boringssl/crypto/pkcs8/p5_pbe.c +1 -0
  532. data/third_party/boringssl/crypto/pkcs8/p5_pbev2.c +2 -1
  533. data/third_party/boringssl/crypto/pkcs8/p8_pkey.c +2 -2
  534. data/third_party/boringssl/crypto/pkcs8/pkcs8.c +95 -87
  535. data/third_party/boringssl/crypto/{test/test_util.h → poly1305/internal.h} +15 -10
  536. data/third_party/boringssl/crypto/poly1305/poly1305.c +8 -15
  537. data/third_party/boringssl/crypto/poly1305/poly1305_arm.c +1 -0
  538. data/third_party/boringssl/crypto/poly1305/poly1305_vec.c +3 -3
  539. data/third_party/boringssl/crypto/rand/deterministic.c +47 -0
  540. data/third_party/boringssl/crypto/rand/rand.c +4 -1
  541. data/third_party/boringssl/crypto/rand/urandom.c +5 -7
  542. data/third_party/boringssl/crypto/rand/windows.c +5 -8
  543. data/third_party/boringssl/crypto/rc4/rc4.c +24 -209
  544. data/third_party/boringssl/crypto/refcount_lock.c +2 -2
  545. data/third_party/boringssl/crypto/rsa/blinding.c +74 -232
  546. data/third_party/boringssl/crypto/rsa/internal.h +5 -13
  547. data/third_party/boringssl/crypto/rsa/padding.c +64 -63
  548. data/third_party/boringssl/crypto/rsa/rsa.c +50 -28
  549. data/third_party/boringssl/crypto/rsa/rsa_asn1.c +8 -16
  550. data/third_party/boringssl/crypto/rsa/rsa_impl.c +134 -122
  551. data/third_party/boringssl/crypto/sha/sha256.c +2 -2
  552. data/third_party/boringssl/crypto/sha/sha512.c +7 -7
  553. data/third_party/boringssl/crypto/stack/stack.c +13 -22
  554. data/third_party/boringssl/crypto/thread.c +21 -12
  555. data/third_party/boringssl/crypto/thread_none.c +6 -2
  556. data/third_party/boringssl/crypto/thread_pthread.c +16 -7
  557. data/third_party/boringssl/crypto/thread_win.c +38 -85
  558. data/third_party/boringssl/crypto/x509/a_sign.c +3 -3
  559. data/third_party/boringssl/crypto/x509/a_strex.c +1 -1
  560. data/third_party/boringssl/crypto/x509/a_verify.c +2 -2
  561. data/third_party/boringssl/crypto/{evp → x509}/algorithm.c +37 -53
  562. data/third_party/boringssl/crypto/x509/asn1_gen.c +1 -2
  563. data/third_party/boringssl/crypto/x509/by_dir.c +6 -6
  564. data/third_party/boringssl/crypto/x509/internal.h +66 -0
  565. data/third_party/boringssl/crypto/x509/rsa_pss.c +385 -0
  566. data/third_party/boringssl/crypto/x509/t_x509.c +10 -12
  567. data/third_party/boringssl/crypto/x509/x509.c +5 -0
  568. data/third_party/boringssl/crypto/x509/x509_att.c +9 -3
  569. data/third_party/boringssl/crypto/x509/x509_lu.c +34 -44
  570. data/third_party/boringssl/crypto/x509/x509_obj.c +19 -2
  571. data/third_party/boringssl/crypto/x509/x509_r2x.c +9 -5
  572. data/third_party/boringssl/crypto/x509/x509_set.c +5 -0
  573. data/third_party/boringssl/crypto/x509/x509_txt.c +5 -0
  574. data/third_party/boringssl/crypto/x509/x509_vfy.c +63 -32
  575. data/third_party/boringssl/crypto/x509/x509_vpm.c +29 -18
  576. data/third_party/boringssl/crypto/x509/x509cset.c +2 -1
  577. data/third_party/boringssl/crypto/x509/x_crl.c +2 -2
  578. data/third_party/boringssl/crypto/x509/x_name.c +14 -17
  579. data/third_party/boringssl/crypto/x509/x_pubkey.c +10 -7
  580. data/third_party/boringssl/crypto/x509/x_x509.c +67 -6
  581. data/third_party/boringssl/crypto/x509v3/pcy_cache.c +2 -2
  582. data/third_party/boringssl/crypto/x509v3/pcy_tree.c +2 -1
  583. data/third_party/boringssl/crypto/x509v3/v3_conf.c +4 -3
  584. data/third_party/boringssl/crypto/x509v3/v3_cpols.c +5 -0
  585. data/third_party/boringssl/crypto/x509v3/v3_prn.c +0 -3
  586. data/third_party/boringssl/crypto/x509v3/v3_purp.c +2 -2
  587. data/third_party/boringssl/crypto/x509v3/v3_utl.c +2 -1
  588. data/third_party/boringssl/include/openssl/aead.h +72 -73
  589. data/third_party/boringssl/include/openssl/arm_arch.h +0 -6
  590. data/third_party/boringssl/include/openssl/asn1.h +103 -235
  591. data/third_party/boringssl/include/openssl/asn1_mac.h +17 -74
  592. data/third_party/boringssl/include/openssl/asn1t.h +1 -11
  593. data/third_party/boringssl/include/openssl/base.h +145 -3
  594. data/third_party/boringssl/include/openssl/base64.h +20 -17
  595. data/third_party/boringssl/include/openssl/bio.h +59 -34
  596. data/third_party/boringssl/include/openssl/bn.h +118 -51
  597. data/third_party/boringssl/include/openssl/buf.h +15 -0
  598. data/third_party/boringssl/include/openssl/bytestring.h +52 -4
  599. data/third_party/boringssl/include/openssl/chacha.h +2 -2
  600. data/third_party/boringssl/include/openssl/cipher.h +18 -1
  601. data/third_party/boringssl/include/openssl/cmac.h +11 -0
  602. data/third_party/boringssl/include/openssl/conf.h +13 -2
  603. data/third_party/boringssl/include/openssl/cpu.h +20 -23
  604. data/third_party/boringssl/include/openssl/crypto.h +22 -1
  605. data/third_party/boringssl/include/openssl/curve25519.h +96 -4
  606. data/third_party/boringssl/include/openssl/dh.h +71 -16
  607. data/third_party/boringssl/include/openssl/digest.h +38 -11
  608. data/third_party/boringssl/include/openssl/dsa.h +40 -4
  609. data/third_party/boringssl/include/openssl/ec.h +44 -18
  610. data/third_party/boringssl/include/openssl/ec_key.h +27 -6
  611. data/third_party/boringssl/include/openssl/ecdsa.h +11 -0
  612. data/third_party/boringssl/include/openssl/engine.h +11 -0
  613. data/third_party/boringssl/include/openssl/evp.h +52 -88
  614. data/third_party/boringssl/include/openssl/hkdf.h +24 -4
  615. data/third_party/boringssl/include/openssl/hmac.h +20 -6
  616. data/third_party/boringssl/include/openssl/md4.h +4 -0
  617. data/third_party/boringssl/include/openssl/mem.h +19 -0
  618. data/third_party/boringssl/include/openssl/newhope.h +158 -0
  619. data/third_party/boringssl/include/openssl/nid.h +4166 -0
  620. data/third_party/boringssl/include/openssl/obj.h +31 -3
  621. data/third_party/boringssl/include/openssl/obj_mac.h +17 -4143
  622. data/third_party/boringssl/include/openssl/{opensslfeatures.h → opensslconf.h} +3 -3
  623. data/third_party/boringssl/include/openssl/pem.h +5 -0
  624. data/third_party/boringssl/include/openssl/pkcs8.h +12 -0
  625. data/third_party/boringssl/include/openssl/rand.h +6 -0
  626. data/third_party/boringssl/include/openssl/rc4.h +6 -0
  627. data/third_party/boringssl/{crypto/dh/internal.h → include/openssl/ripemd.h} +38 -11
  628. data/third_party/boringssl/include/openssl/rsa.h +127 -65
  629. data/third_party/boringssl/include/openssl/sha.h +14 -10
  630. data/third_party/boringssl/include/openssl/ssl.h +561 -275
  631. data/third_party/boringssl/include/openssl/ssl3.h +18 -25
  632. data/third_party/boringssl/include/openssl/stack.h +2 -4
  633. data/third_party/boringssl/include/openssl/stack_macros.h +321 -353
  634. data/third_party/boringssl/include/openssl/thread.h +31 -13
  635. data/third_party/boringssl/include/openssl/time_support.h +1 -0
  636. data/third_party/boringssl/include/openssl/tls1.h +37 -33
  637. data/third_party/boringssl/include/openssl/x509.h +69 -26
  638. data/third_party/boringssl/include/openssl/x509_vfy.h +12 -10
  639. data/third_party/boringssl/include/openssl/x509v3.h +23 -2
  640. data/third_party/boringssl/ssl/custom_extensions.c +3 -5
  641. data/third_party/boringssl/ssl/d1_both.c +463 -499
  642. data/third_party/boringssl/ssl/d1_lib.c +38 -109
  643. data/third_party/boringssl/ssl/d1_pkt.c +173 -334
  644. data/third_party/boringssl/ssl/d1_srtp.c +20 -18
  645. data/third_party/boringssl/ssl/{d1_meth.c → dtls_method.c} +88 -15
  646. data/third_party/boringssl/ssl/dtls_record.c +27 -26
  647. data/third_party/boringssl/ssl/{s3_clnt.c → handshake_client.c} +816 -904
  648. data/third_party/boringssl/ssl/handshake_server.c +1932 -0
  649. data/third_party/boringssl/ssl/internal.h +712 -439
  650. data/third_party/boringssl/ssl/s3_both.c +445 -257
  651. data/third_party/boringssl/ssl/s3_enc.c +53 -36
  652. data/third_party/boringssl/ssl/s3_lib.c +23 -268
  653. data/third_party/boringssl/ssl/s3_pkt.c +168 -364
  654. data/third_party/boringssl/ssl/ssl_aead_ctx.c +46 -17
  655. data/third_party/boringssl/ssl/ssl_asn1.c +56 -26
  656. data/third_party/boringssl/ssl/ssl_buffer.c +16 -24
  657. data/third_party/boringssl/ssl/ssl_cert.c +324 -49
  658. data/third_party/boringssl/ssl/ssl_cipher.c +205 -150
  659. data/third_party/boringssl/ssl/ssl_ecdh.c +287 -51
  660. data/third_party/boringssl/ssl/ssl_file.c +21 -68
  661. data/third_party/boringssl/ssl/ssl_lib.c +881 -510
  662. data/third_party/boringssl/ssl/ssl_rsa.c +404 -34
  663. data/third_party/boringssl/ssl/ssl_session.c +324 -103
  664. data/third_party/boringssl/ssl/ssl_stat.c +6 -88
  665. data/third_party/boringssl/ssl/t1_enc.c +23 -39
  666. data/third_party/boringssl/ssl/t1_lib.c +1120 -622
  667. data/third_party/boringssl/ssl/tls13_both.c +440 -0
  668. data/third_party/boringssl/ssl/tls13_client.c +682 -0
  669. data/third_party/boringssl/ssl/tls13_enc.c +391 -0
  670. data/third_party/boringssl/ssl/tls13_server.c +672 -0
  671. data/third_party/boringssl/ssl/{s3_meth.c → tls_method.c} +100 -21
  672. data/third_party/boringssl/ssl/tls_record.c +159 -77
  673. data/third_party/nanopb/pb.h +60 -28
  674. data/third_party/nanopb/pb_decode.c +120 -92
  675. data/third_party/nanopb/pb_decode.h +3 -3
  676. data/third_party/nanopb/pb_encode.c +73 -67
  677. data/third_party/nanopb/pb_encode.h +4 -4
  678. metadata +155 -89
  679. data/include/grpc/impl/codegen/byte_buffer.h +0 -122
  680. data/include/grpc/impl/codegen/log.h +0 -118
  681. data/include/grpc/impl/codegen/time.h +0 -130
  682. data/src/core/ext/client_config/client_channel.c +0 -593
  683. data/src/core/ext/client_config/subchannel_call_holder.c +0 -272
  684. data/src/core/ext/client_config/subchannel_call_holder.h +0 -99
  685. data/src/core/lib/iomgr/ev_poll_and_epoll_posix.c +0 -2046
  686. data/src/core/lib/iomgr/workqueue_posix.c +0 -151
  687. data/src/core/lib/security/transport/handshake.c +0 -368
  688. data/third_party/boringssl/crypto/asn1/a_bytes.c +0 -308
  689. data/third_party/boringssl/crypto/asn1/bio_asn1.c +0 -477
  690. data/third_party/boringssl/crypto/asn1/bio_ndef.c +0 -251
  691. data/third_party/boringssl/crypto/asn1/t_pkey.c +0 -110
  692. data/third_party/boringssl/crypto/asn1/tasn_prn.c +0 -596
  693. data/third_party/boringssl/crypto/chacha/chacha_vec.c +0 -328
  694. data/third_party/boringssl/crypto/directory.h +0 -66
  695. data/third_party/boringssl/crypto/directory_posix.c +0 -108
  696. data/third_party/boringssl/crypto/directory_win.c +0 -144
  697. data/third_party/boringssl/crypto/test/scoped_types.h +0 -140
  698. data/third_party/boringssl/include/openssl/pqueue.h +0 -146
  699. data/third_party/boringssl/ssl/d1_clnt.c +0 -561
  700. data/third_party/boringssl/ssl/d1_srvr.c +0 -476
  701. data/third_party/boringssl/ssl/pqueue/pqueue.c +0 -197
  702. data/third_party/boringssl/ssl/s3_srvr.c +0 -2272
  703. data/third_party/boringssl/ssl/test/async_bio.h +0 -45
  704. data/third_party/boringssl/ssl/test/packeted_bio.h +0 -44
  705. data/third_party/boringssl/ssl/test/test_config.h +0 -110
@@ -34,12 +34,12 @@
34
34
  #include "src/core/lib/iomgr/endpoint.h"
35
35
 
36
36
  void grpc_endpoint_read(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep,
37
- gpr_slice_buffer* slices, grpc_closure* cb) {
37
+ grpc_slice_buffer* slices, grpc_closure* cb) {
38
38
  ep->vtable->read(exec_ctx, ep, slices, cb);
39
39
  }
40
40
 
41
41
  void grpc_endpoint_write(grpc_exec_ctx* exec_ctx, grpc_endpoint* ep,
42
- gpr_slice_buffer* slices, grpc_closure* cb) {
42
+ grpc_slice_buffer* slices, grpc_closure* cb) {
43
43
  ep->vtable->write(exec_ctx, ep, slices, cb);
44
44
  }
45
45
 
@@ -66,6 +66,12 @@ char* grpc_endpoint_get_peer(grpc_endpoint* ep) {
66
66
  return ep->vtable->get_peer(ep);
67
67
  }
68
68
 
69
+ int grpc_endpoint_get_fd(grpc_endpoint* ep) { return ep->vtable->get_fd(ep); }
70
+
69
71
  grpc_workqueue* grpc_endpoint_get_workqueue(grpc_endpoint* ep) {
70
72
  return ep->vtable->get_workqueue(ep);
71
73
  }
74
+
75
+ grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* ep) {
76
+ return ep->vtable->get_resource_user(ep);
77
+ }
@@ -34,11 +34,12 @@
34
34
  #ifndef GRPC_CORE_LIB_IOMGR_ENDPOINT_H
35
35
  #define GRPC_CORE_LIB_IOMGR_ENDPOINT_H
36
36
 
37
- #include <grpc/support/slice.h>
38
- #include <grpc/support/slice_buffer.h>
37
+ #include <grpc/slice.h>
38
+ #include <grpc/slice_buffer.h>
39
39
  #include <grpc/support/time.h>
40
40
  #include "src/core/lib/iomgr/pollset.h"
41
41
  #include "src/core/lib/iomgr/pollset_set.h"
42
+ #include "src/core/lib/iomgr/resource_quota.h"
42
43
 
43
44
  /* An endpoint caps a streaming channel between two communicating processes.
44
45
  Examples may be: a tcp socket, <stdin+stdout>, or some shared memory. */
@@ -48,9 +49,9 @@ typedef struct grpc_endpoint_vtable grpc_endpoint_vtable;
48
49
 
49
50
  struct grpc_endpoint_vtable {
50
51
  void (*read)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
51
- gpr_slice_buffer *slices, grpc_closure *cb);
52
+ grpc_slice_buffer *slices, grpc_closure *cb);
52
53
  void (*write)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
53
- gpr_slice_buffer *slices, grpc_closure *cb);
54
+ grpc_slice_buffer *slices, grpc_closure *cb);
54
55
  grpc_workqueue *(*get_workqueue)(grpc_endpoint *ep);
55
56
  void (*add_to_pollset)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
56
57
  grpc_pollset *pollset);
@@ -58,18 +59,25 @@ struct grpc_endpoint_vtable {
58
59
  grpc_pollset_set *pollset);
59
60
  void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep);
60
61
  void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep);
62
+ grpc_resource_user *(*get_resource_user)(grpc_endpoint *ep);
61
63
  char *(*get_peer)(grpc_endpoint *ep);
64
+ int (*get_fd)(grpc_endpoint *ep);
62
65
  };
63
66
 
64
67
  /* When data is available on the connection, calls the callback with slices.
65
68
  Callback success indicates that the endpoint can accept more reads, failure
66
69
  indicates the endpoint is closed.
67
- Valid slices may be placed into \a slices even on callback success == 0. */
70
+ Valid slices may be placed into \a slices even when the callback is
71
+ invoked with error != GRPC_ERROR_NONE. */
68
72
  void grpc_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
69
- gpr_slice_buffer *slices, grpc_closure *cb);
73
+ grpc_slice_buffer *slices, grpc_closure *cb);
70
74
 
71
75
  char *grpc_endpoint_get_peer(grpc_endpoint *ep);
72
76
 
77
+ /* Get the file descriptor used by \a ep. Return -1 if \a ep is not using an fd.
78
+ */
79
+ int grpc_endpoint_get_fd(grpc_endpoint *ep);
80
+
73
81
  /* Retrieve a reference to the workqueue associated with this endpoint */
74
82
  grpc_workqueue *grpc_endpoint_get_workqueue(grpc_endpoint *ep);
75
83
 
@@ -84,7 +92,7 @@ grpc_workqueue *grpc_endpoint_get_workqueue(grpc_endpoint *ep);
84
92
  it is a valid slice buffer.
85
93
  */
86
94
  void grpc_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
87
- gpr_slice_buffer *slices, grpc_closure *cb);
95
+ grpc_slice_buffer *slices, grpc_closure *cb);
88
96
 
89
97
  /* Causes any pending and future read/write callbacks to run immediately with
90
98
  success==0 */
@@ -99,6 +107,8 @@ void grpc_endpoint_add_to_pollset_set(grpc_exec_ctx *exec_ctx,
99
107
  grpc_endpoint *ep,
100
108
  grpc_pollset_set *pollset_set);
101
109
 
110
+ grpc_resource_user *grpc_endpoint_get_resource_user(grpc_endpoint *endpoint);
111
+
102
112
  struct grpc_endpoint {
103
113
  const grpc_endpoint_vtable *vtable;
104
114
  };
@@ -41,7 +41,8 @@ typedef struct {
41
41
  grpc_endpoint *server;
42
42
  } grpc_endpoint_pair;
43
43
 
44
- grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,
45
- size_t read_slice_size);
44
+ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
45
+ const char *name, grpc_resource_quota *resource_quota,
46
+ size_t read_slice_size);
46
47
 
47
48
  #endif /* GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H */
@@ -31,9 +31,9 @@
31
31
  *
32
32
  */
33
33
 
34
- #include <grpc/support/port_platform.h>
34
+ #include "src/core/lib/iomgr/port.h"
35
35
 
36
- #ifdef GPR_POSIX_SOCKET
36
+ #ifdef GRPC_POSIX_SOCKET
37
37
 
38
38
  #include "src/core/lib/iomgr/endpoint_pair.h"
39
39
  #include "src/core/lib/iomgr/socket_utils_posix.h"
@@ -62,20 +62,21 @@ 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(const char *name,
66
- size_t read_slice_size) {
65
+ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
66
+ const char *name, grpc_resource_quota *resource_quota,
67
+ size_t read_slice_size) {
67
68
  int sv[2];
68
69
  grpc_endpoint_pair p;
69
70
  char *final_name;
70
71
  create_sockets(sv);
71
72
 
72
73
  gpr_asprintf(&final_name, "%s:client", name);
73
- p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name), read_slice_size,
74
- "socketpair-server");
74
+ p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name), resource_quota,
75
+ read_slice_size, "socketpair-server");
75
76
  gpr_free(final_name);
76
77
  gpr_asprintf(&final_name, "%s:server", name);
77
- p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name), read_slice_size,
78
- "socketpair-client");
78
+ p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name), resource_quota,
79
+ read_slice_size, "socketpair-client");
79
80
  gpr_free(final_name);
80
81
  return p;
81
82
  }
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  *
3
- * Copyright 2015, Google Inc.
3
+ * Copyright 2016, Google Inc.
4
4
  * All rights reserved.
5
5
  *
6
6
  * Redistribution and use in source and binary forms, with or without
@@ -31,19 +31,24 @@
31
31
  *
32
32
  */
33
33
 
34
- #include "src/core/ext/client_config/lb_policy_factory.h"
34
+ #include "src/core/lib/iomgr/port.h"
35
35
 
36
- void grpc_lb_policy_factory_ref(grpc_lb_policy_factory* factory) {
37
- factory->vtable->ref(factory);
38
- }
36
+ #ifdef GRPC_UV
39
37
 
40
- void grpc_lb_policy_factory_unref(grpc_lb_policy_factory* factory) {
41
- factory->vtable->unref(factory);
42
- }
38
+ #include <stdlib.h>
39
+
40
+ #include <grpc/support/log.h>
43
41
 
44
- grpc_lb_policy* grpc_lb_policy_factory_create_lb_policy(
45
- grpc_exec_ctx* exec_ctx, grpc_lb_policy_factory* factory,
46
- grpc_lb_policy_args* args) {
47
- if (factory == NULL) return NULL;
48
- return factory->vtable->create_lb_policy(exec_ctx, factory, args);
42
+ #include "src/core/lib/iomgr/endpoint_pair.h"
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) {
47
+ grpc_endpoint_pair endpoint_pair;
48
+ // TODO(mlumish): implement this properly under libuv
49
+ GPR_ASSERT(false &&
50
+ "grpc_iomgr_create_endpoint_pair is not suppoted with libuv");
51
+ return endpoint_pair;
49
52
  }
53
+
54
+ #endif /* GRPC_UV */
@@ -31,9 +31,9 @@
31
31
  *
32
32
  */
33
33
 
34
- #include <grpc/support/port_platform.h>
34
+ #include "src/core/lib/iomgr/port.h"
35
35
 
36
- #ifdef GPR_WINSOCK_SOCKET
36
+ #ifdef GRPC_WINSOCK_SOCKET
37
37
  #include "src/core/lib/iomgr/endpoint_pair.h"
38
38
  #include "src/core/lib/iomgr/sockaddr_utils.h"
39
39
 
@@ -82,15 +82,16 @@ static void create_sockets(SOCKET sv[2]) {
82
82
  sv[0] = svr_sock;
83
83
  }
84
84
 
85
- grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,
86
- size_t read_slice_size) {
85
+ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(
86
+ const char *name, grpc_resource_quota *resource_quota,
87
+ size_t read_slice_size) {
87
88
  SOCKET sv[2];
88
89
  grpc_endpoint_pair p;
89
90
  create_sockets(sv);
90
91
  p.client = grpc_tcp_create(grpc_winsocket_create(sv[1], "endpoint:client"),
91
- "endpoint:server");
92
+ resource_quota, "endpoint:server");
92
93
  p.server = grpc_tcp_create(grpc_winsocket_create(sv[0], "endpoint:server"),
93
- "endpoint:client");
94
+ resource_quota, "endpoint:client");
94
95
  return p;
95
96
  }
96
97
 
@@ -120,6 +120,8 @@ static const char *error_int_name(grpc_error_ints key) {
120
120
  return "http_status";
121
121
  case GRPC_ERROR_INT_LIMIT:
122
122
  return "limit";
123
+ case GRPC_ERROR_INT_OCCURRED_DURING_WRITE:
124
+ return "occurred_during_write";
123
125
  }
124
126
  GPR_UNREACHABLE_CODE(return "unknown");
125
127
  }
@@ -144,6 +146,8 @@ static const char *error_str_name(grpc_error_strs key) {
144
146
  return "tsi_error";
145
147
  case GRPC_ERROR_STR_FILENAME:
146
148
  return "filename";
149
+ case GRPC_ERROR_STR_QUEUED_BUFFERS:
150
+ return "queued_buffers";
147
151
  }
148
152
  GPR_UNREACHABLE_CODE(return "unknown");
149
153
  }
@@ -265,7 +269,7 @@ static grpc_error *copy_error_and_unref(grpc_error *in) {
265
269
  } else {
266
270
  out = gpr_malloc(sizeof(*out));
267
271
  #ifdef GRPC_ERROR_REFCOUNT_DEBUG
268
- gpr_log(GPR_DEBUG, "%p create copying", out);
272
+ gpr_log(GPR_DEBUG, "%p create copying %p", out, in);
269
273
  #endif
270
274
  out->ints = gpr_avl_ref(in->ints);
271
275
  out->strs = gpr_avl_ref(in->strs);
@@ -324,6 +328,64 @@ const char *grpc_error_get_str(grpc_error *err, grpc_error_strs which) {
324
328
  return gpr_avl_get(err->strs, (void *)(uintptr_t)which);
325
329
  }
326
330
 
331
+ typedef struct {
332
+ grpc_error *error;
333
+ grpc_status_code code;
334
+ const char *msg;
335
+ } special_error_status_map;
336
+ static special_error_status_map error_status_map[] = {
337
+ {GRPC_ERROR_NONE, GRPC_STATUS_OK, ""},
338
+ {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "RPC cancelled"},
339
+ {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"},
340
+ };
341
+
342
+ static grpc_error *recursively_find_error_with_status(grpc_error *error,
343
+ intptr_t *status) {
344
+ // If the error itself has a status code, return it.
345
+ if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, status)) {
346
+ return error;
347
+ }
348
+ // Otherwise, search through its children.
349
+ intptr_t key = 0;
350
+ while (true) {
351
+ grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++);
352
+ if (child_error == NULL) break;
353
+ grpc_error *result =
354
+ recursively_find_error_with_status(child_error, status);
355
+ if (result != NULL) return result;
356
+ }
357
+ return NULL;
358
+ }
359
+
360
+ void grpc_error_get_status(grpc_error *error, grpc_status_code *code,
361
+ const char **msg) {
362
+ // Handle special errors via the static map.
363
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); ++i) {
364
+ if (error == error_status_map[i].error) {
365
+ *code = error_status_map[i].code;
366
+ *msg = error_status_map[i].msg;
367
+ return;
368
+ }
369
+ }
370
+ // Populate code.
371
+ // Start with the parent error and recurse through the tree of children
372
+ // until we find the first one that has a status code.
373
+ intptr_t status = GRPC_STATUS_UNKNOWN; // Default in case we don't find one.
374
+ grpc_error *found_error = recursively_find_error_with_status(error, &status);
375
+ *code = (grpc_status_code)status;
376
+ // Now populate msg.
377
+ // If we found an error with a status code above, use that; otherwise,
378
+ // fall back to using the parent error.
379
+ if (found_error == NULL) found_error = error;
380
+ // If the error has a status message, use it. Otherwise, fall back to
381
+ // the error description.
382
+ *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_GRPC_MESSAGE);
383
+ if (*msg == NULL) {
384
+ *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_DESCRIPTION);
385
+ if (*msg == NULL) *msg = "uknown error"; // Just in case.
386
+ }
387
+ }
388
+
327
389
  grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) {
328
390
  GPR_TIMER_BEGIN("grpc_error_add_child", 0);
329
391
  grpc_error *new = copy_error_and_unref(src);
@@ -332,7 +394,7 @@ grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) {
332
394
  return new;
333
395
  }
334
396
 
335
- static const char *no_error_string = "null";
397
+ static const char *no_error_string = "\"No Error\"";
336
398
  static const char *oom_error_string = "\"Out of memory\"";
337
399
  static const char *cancelled_error_string = "\"Cancelled\"";
338
400
 
@@ -465,21 +527,25 @@ static char *fmt_time(void *p) {
465
527
  return out;
466
528
  }
467
529
 
468
- static void add_errs(gpr_avl_node *n, char **s, size_t *sz, size_t *cap) {
530
+ static void add_errs(gpr_avl_node *n, char **s, size_t *sz, size_t *cap,
531
+ bool *first) {
469
532
  if (n == NULL) return;
470
- add_errs(n->left, s, sz, cap);
533
+ add_errs(n->left, s, sz, cap, first);
534
+ if (!*first) append_chr(',', s, sz, cap);
535
+ *first = false;
471
536
  const char *e = grpc_error_string(n->value);
472
537
  append_str(e, s, sz, cap);
473
538
  grpc_error_free_string(e);
474
- add_errs(n->right, s, sz, cap);
539
+ add_errs(n->right, s, sz, cap, first);
475
540
  }
476
541
 
477
542
  static char *errs_string(grpc_error *err) {
478
543
  char *s = NULL;
479
544
  size_t sz = 0;
480
545
  size_t cap = 0;
546
+ bool first = true;
481
547
  append_chr('[', &s, &sz, &cap);
482
- add_errs(err->errs.root, &s, &sz, &cap);
548
+ add_errs(err->errs.root, &s, &sz, &cap, &first);
483
549
  append_chr(']', &s, &sz, &cap);
484
550
  append_chr(0, &s, &sz, &cap);
485
551
  return s;
@@ -37,8 +37,13 @@
37
37
  #include <stdbool.h>
38
38
  #include <stdint.h>
39
39
 
40
+ #include <grpc/status.h>
40
41
  #include <grpc/support/time.h>
41
42
 
43
+ #ifdef __cplusplus
44
+ extern "C" {
45
+ #endif
46
+
42
47
  /// Opaque representation of an error.
43
48
  /// Errors are refcounted objects that represent the result of an operation.
44
49
  /// Ownership laws:
@@ -47,7 +52,8 @@
47
52
  /// if a grpc_error is passed to a grpc_closure callback function (functions
48
53
  /// with the signature:
49
54
  /// void (*f)(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error))
50
- /// then those functions do not automatically own a ref to error
55
+ /// then those functions do not own a ref to error (but are free to manually
56
+ /// take a reference).
51
57
  /// if a grpc_error is passed to *ANY OTHER FUNCTION* then that function takes
52
58
  /// ownership of the error
53
59
  /// Errors have:
@@ -94,6 +100,8 @@ typedef enum {
94
100
  GRPC_ERROR_INT_HTTP_STATUS,
95
101
  /// context sensitive limit associated with the error
96
102
  GRPC_ERROR_INT_LIMIT,
103
+ /// chttp2: did the error occur while a write was in progress
104
+ GRPC_ERROR_INT_OCCURRED_DURING_WRITE,
97
105
  } grpc_error_ints;
98
106
 
99
107
  typedef enum {
@@ -115,6 +123,8 @@ typedef enum {
115
123
  GRPC_ERROR_STR_TSI_ERROR,
116
124
  /// filename that we were trying to read/write when this error occurred
117
125
  GRPC_ERROR_STR_FILENAME,
126
+ /// which data was queued for writing when the error occurred
127
+ GRPC_ERROR_STR_QUEUED_BUFFERS
118
128
  } grpc_error_strs;
119
129
 
120
130
  typedef enum {
@@ -122,9 +132,13 @@ typedef enum {
122
132
  GRPC_ERROR_TIME_CREATED,
123
133
  } grpc_error_times;
124
134
 
135
+ /// The following "special" errors can be propagated without allocating memory.
136
+ /// They are always even so that other code (particularly combiner locks) can
137
+ /// safely use the lower bit for themselves.
138
+
125
139
  #define GRPC_ERROR_NONE ((grpc_error *)NULL)
126
- #define GRPC_ERROR_OOM ((grpc_error *)1)
127
- #define GRPC_ERROR_CANCELLED ((grpc_error *)2)
140
+ #define GRPC_ERROR_OOM ((grpc_error *)2)
141
+ #define GRPC_ERROR_CANCELLED ((grpc_error *)4)
128
142
 
129
143
  const char *grpc_error_string(grpc_error *error);
130
144
  void grpc_error_free_string(const char *str);
@@ -171,7 +185,16 @@ grpc_error *grpc_error_set_time(grpc_error *src, grpc_error_times which,
171
185
  gpr_timespec value) GRPC_MUST_USE_RESULT;
172
186
  grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
173
187
  const char *value) GRPC_MUST_USE_RESULT;
188
+ /// Returns NULL if the specified string is not set.
189
+ /// Caller does NOT own return value.
174
190
  const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which);
191
+
192
+ /// A utility function to get the status code and message to be returned
193
+ /// to the application. If not set in the top-level message, looks
194
+ /// through child errors until it finds the first one with these attributes.
195
+ void grpc_error_get_status(grpc_error *error, grpc_status_code *code,
196
+ const char **msg);
197
+
175
198
  /// Add a child error: an error that is believed to have contributed to this
176
199
  /// error occurring. Allows root causing high level errors from lower level
177
200
  /// errors that contributed to them.
@@ -193,4 +216,8 @@ bool grpc_log_if_error(const char *what, grpc_error *error, const char *file,
193
216
  #define GRPC_LOG_IF_ERROR(what, error) \
194
217
  grpc_log_if_error((what), (error), __FILE__, __LINE__)
195
218
 
219
+ #ifdef __cplusplus
220
+ }
221
+ #endif
222
+
196
223
  #endif /* GRPC_CORE_LIB_IOMGR_ERROR_H */
@@ -31,17 +31,17 @@
31
31
  *
32
32
  */
33
33
 
34
- #include <grpc/grpc_posix.h>
35
- #include <grpc/support/port_platform.h>
34
+ #include "src/core/lib/iomgr/port.h"
36
35
 
37
36
  /* This polling engine is only relevant on linux kernels supporting epoll() */
38
- #ifdef GPR_LINUX_EPOLL
37
+ #ifdef GRPC_LINUX_EPOLL
39
38
 
40
39
  #include "src/core/lib/iomgr/ev_epoll_linux.h"
41
40
 
42
41
  #include <assert.h>
43
42
  #include <errno.h>
44
43
  #include <poll.h>
44
+ #include <pthread.h>
45
45
  #include <signal.h>
46
46
  #include <string.h>
47
47
  #include <sys/epoll.h>
@@ -68,9 +68,17 @@ static int grpc_polling_trace = 0; /* Disabled by default */
68
68
  gpr_log(GPR_INFO, (fmt), __VA_ARGS__); \
69
69
  }
70
70
 
71
+ /* Uncomment the following enable extra checks on poll_object operations */
72
+ /* #define PO_DEBUG */
73
+
71
74
  static int grpc_wakeup_signal = -1;
72
75
  static bool is_grpc_wakeup_signal_initialized = false;
73
76
 
77
+ /* TODO: sreek: Right now, this wakes up all pollers. In future we should make
78
+ * sure to wake up one polling thread (which can wake up other threads if
79
+ * needed) */
80
+ static grpc_wakeup_fd global_wakeup_fd;
81
+
74
82
  /* Implements the function defined in grpc_posix.h. This function might be
75
83
  * called before even calling grpc_init() to set either a different signal to
76
84
  * use. If signum == -1, then the use of signals is disabled */
@@ -89,10 +97,42 @@ void grpc_use_signal(int signum) {
89
97
 
90
98
  struct polling_island;
91
99
 
100
+ typedef enum {
101
+ POLL_OBJ_FD,
102
+ POLL_OBJ_POLLSET,
103
+ POLL_OBJ_POLLSET_SET
104
+ } poll_obj_type;
105
+
106
+ typedef struct poll_obj {
107
+ #ifdef PO_DEBUG
108
+ poll_obj_type obj_type;
109
+ #endif
110
+ gpr_mu mu;
111
+ struct polling_island *pi;
112
+ } poll_obj;
113
+
114
+ const char *poll_obj_string(poll_obj_type po_type) {
115
+ switch (po_type) {
116
+ case POLL_OBJ_FD:
117
+ return "fd";
118
+ case POLL_OBJ_POLLSET:
119
+ return "pollset";
120
+ case POLL_OBJ_POLLSET_SET:
121
+ return "pollset_set";
122
+ }
123
+
124
+ GPR_UNREACHABLE_CODE(return "UNKNOWN");
125
+ }
126
+
92
127
  /*******************************************************************************
93
128
  * Fd Declarations
94
129
  */
130
+
131
+ #define FD_FROM_PO(po) ((grpc_fd *)(po))
132
+
95
133
  struct grpc_fd {
134
+ poll_obj po;
135
+
96
136
  int fd;
97
137
  /* refst format:
98
138
  bit 0 : 1=Active / 0=Orphaned
@@ -100,8 +140,6 @@ struct grpc_fd {
100
140
  Ref/Unref by two to avoid altering the orphaned bit */
101
141
  gpr_atm refst;
102
142
 
103
- gpr_mu mu;
104
-
105
143
  /* Indicates that the fd is shutdown and that any pending read/write closures
106
144
  should fail */
107
145
  bool shutdown;
@@ -114,9 +152,6 @@ struct grpc_fd {
114
152
  grpc_closure *read_closure;
115
153
  grpc_closure *write_closure;
116
154
 
117
- /* The polling island to which this fd belongs to (protected by mu) */
118
- struct polling_island *polling_island;
119
-
120
155
  struct grpc_fd *freelist_next;
121
156
  grpc_closure *on_done_closure;
122
157
 
@@ -151,21 +186,23 @@ static void fd_global_shutdown(void);
151
186
  * Polling island Declarations
152
187
  */
153
188
 
154
- //#define GRPC_PI_REF_COUNT_DEBUG
155
- #ifdef GRPC_PI_REF_COUNT_DEBUG
189
+ #ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG
156
190
 
157
191
  #define PI_ADD_REF(p, r) pi_add_ref_dbg((p), (r), __FILE__, __LINE__)
158
192
  #define PI_UNREF(exec_ctx, p, r) \
159
193
  pi_unref_dbg((exec_ctx), (p), (r), __FILE__, __LINE__)
160
194
 
161
- #else /* defined(GRPC_PI_REF_COUNT_DEBUG) */
195
+ #else /* defined(GRPC_WORKQUEUE_REFCOUNT_DEBUG) */
162
196
 
163
197
  #define PI_ADD_REF(p, r) pi_add_ref((p))
164
198
  #define PI_UNREF(exec_ctx, p, r) pi_unref((exec_ctx), (p))
165
199
 
166
- #endif /* !defined(GPRC_PI_REF_COUNT_DEBUG) */
200
+ #endif /* !defined(GRPC_PI_REF_COUNT_DEBUG) */
167
201
 
202
+ /* This is also used as grpc_workqueue (by directly casing it) */
168
203
  typedef struct polling_island {
204
+ grpc_closure_scheduler workqueue_scheduler;
205
+
169
206
  gpr_mu mu;
170
207
  /* Ref count. Use PI_ADD_REF() and PI_UNREF() macros to increment/decrement
171
208
  the refcount.
@@ -184,8 +221,17 @@ typedef struct polling_island {
184
221
  * (except mu and ref_count) are invalid and must be ignored. */
185
222
  gpr_atm merged_to;
186
223
 
187
- /* The workqueue associated with this polling island */
188
- grpc_workqueue *workqueue;
224
+ /* Number of threads currently polling on this island */
225
+ gpr_atm poller_count;
226
+ /* Mutex guarding the read end of the workqueue (must be held to pop from
227
+ * workqueue_items) */
228
+ gpr_mu workqueue_read_mu;
229
+ /* Queue of closures to be executed */
230
+ gpr_mpscq workqueue_items;
231
+ /* Count of items in workqueue_items */
232
+ gpr_atm workqueue_item_count;
233
+ /* Wakeup fd used to wake pollers to check the contents of workqueue_items */
234
+ grpc_wakeup_fd workqueue_wakeup_fd;
189
235
 
190
236
  /* The fd of the underlying epoll set */
191
237
  int epoll_fd;
@@ -210,41 +256,21 @@ struct grpc_pollset_worker {
210
256
  };
211
257
 
212
258
  struct grpc_pollset {
213
- gpr_mu mu;
259
+ poll_obj po;
260
+
214
261
  grpc_pollset_worker root_worker;
215
262
  bool kicked_without_pollers;
216
263
 
217
264
  bool shutting_down; /* Is the pollset shutting down ? */
218
265
  bool finish_shutdown_called; /* Is the 'finish_shutdown_locked()' called ? */
219
266
  grpc_closure *shutdown_done; /* Called after after shutdown is complete */
220
-
221
- /* The polling island to which this pollset belongs to */
222
- struct polling_island *polling_island;
223
267
  };
224
268
 
225
269
  /*******************************************************************************
226
270
  * Pollset-set Declarations
227
271
  */
228
- /* TODO: sreek - Change the pollset_set implementation such that a pollset_set
229
- * directly points to a polling_island (and adding an fd/pollset/pollset_set to
230
- * the current pollset_set would result in polling island merges. This would
231
- * remove the need to maintain fd_count here. This will also significantly
232
- * simplify the grpc_fd structure since we would no longer need to explicitly
233
- * maintain the orphaned state */
234
272
  struct grpc_pollset_set {
235
- gpr_mu mu;
236
-
237
- size_t pollset_count;
238
- size_t pollset_capacity;
239
- grpc_pollset **pollsets;
240
-
241
- size_t pollset_set_count;
242
- size_t pollset_set_capacity;
243
- struct grpc_pollset_set **pollset_sets;
244
-
245
- size_t fd_count;
246
- size_t fd_capacity;
247
- grpc_fd **fds;
273
+ poll_obj po;
248
274
  };
249
275
 
250
276
  /*******************************************************************************
@@ -274,8 +300,14 @@ static bool append_error(grpc_error **composite, grpc_error *error,
274
300
  threads that woke up MUST NOT call grpc_wakeup_fd_consume_wakeup() */
275
301
  static grpc_wakeup_fd polling_island_wakeup_fd;
276
302
 
303
+ /* The polling island being polled right now.
304
+ See comments in workqueue_maybe_wakeup for why this is tracked. */
305
+ static __thread polling_island *g_current_thread_polling_island;
306
+
277
307
  /* Forward declaration */
278
308
  static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi);
309
+ static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
310
+ grpc_error *error);
279
311
 
280
312
  #ifdef GRPC_TSAN
281
313
  /* Currently TSAN may incorrectly flag data races between epoll_ctl and
@@ -288,12 +320,15 @@ static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi);
288
320
  gpr_atm g_epoll_sync;
289
321
  #endif /* defined(GRPC_TSAN) */
290
322
 
291
- #ifdef GRPC_PI_REF_COUNT_DEBUG
323
+ static const grpc_closure_scheduler_vtable workqueue_scheduler_vtable = {
324
+ workqueue_enqueue, workqueue_enqueue};
325
+
292
326
  static void pi_add_ref(polling_island *pi);
293
327
  static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi);
294
328
 
295
- static void pi_add_ref_dbg(polling_island *pi, char *reason, char *file,
296
- int line) {
329
+ #ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG
330
+ static void pi_add_ref_dbg(polling_island *pi, const char *reason,
331
+ const char *file, int line) {
297
332
  long old_cnt = gpr_atm_acq_load(&pi->ref_count);
298
333
  pi_add_ref(pi);
299
334
  gpr_log(GPR_DEBUG, "Add ref pi: %p, old: %ld -> new:%ld (%s) - (%s, %d)",
@@ -301,12 +336,42 @@ static void pi_add_ref_dbg(polling_island *pi, char *reason, char *file,
301
336
  }
302
337
 
303
338
  static void pi_unref_dbg(grpc_exec_ctx *exec_ctx, polling_island *pi,
304
- char *reason, char *file, int line) {
339
+ const char *reason, const char *file, int line) {
305
340
  long old_cnt = gpr_atm_acq_load(&pi->ref_count);
306
341
  pi_unref(exec_ctx, pi);
307
342
  gpr_log(GPR_DEBUG, "Unref pi: %p, old:%ld -> new:%ld (%s) - (%s, %d)",
308
343
  (void *)pi, old_cnt, (old_cnt - 1), reason, file, line);
309
344
  }
345
+
346
+ static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue,
347
+ const char *file, int line,
348
+ const char *reason) {
349
+ if (workqueue != NULL) {
350
+ pi_add_ref_dbg((polling_island *)workqueue, reason, file, line);
351
+ }
352
+ return workqueue;
353
+ }
354
+
355
+ static void workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue,
356
+ const char *file, int line, const char *reason) {
357
+ if (workqueue != NULL) {
358
+ pi_unref_dbg(exec_ctx, (polling_island *)workqueue, reason, file, line);
359
+ }
360
+ }
361
+ #else
362
+ static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue) {
363
+ if (workqueue != NULL) {
364
+ pi_add_ref((polling_island *)workqueue);
365
+ }
366
+ return workqueue;
367
+ }
368
+
369
+ static void workqueue_unref(grpc_exec_ctx *exec_ctx,
370
+ grpc_workqueue *workqueue) {
371
+ if (workqueue != NULL) {
372
+ pi_unref(exec_ctx, (polling_island *)workqueue);
373
+ }
374
+ }
310
375
  #endif
311
376
 
312
377
  static void pi_add_ref(polling_island *pi) {
@@ -314,10 +379,7 @@ static void pi_add_ref(polling_island *pi) {
314
379
  }
315
380
 
316
381
  static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi) {
317
- /* If ref count went to one, we're back to just the workqueue owning a ref.
318
- Unref the workqueue to break the loop.
319
-
320
- If ref count went to zero, delete the polling island.
382
+ /* If ref count went to zero, delete the polling island.
321
383
  Note that this deletion not be done under a lock. Once the ref count goes
322
384
  to zero, we are guaranteed that no one else holds a reference to the
323
385
  polling island (and that there is no racing pi_add_ref() call either).
@@ -325,20 +387,12 @@ static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi) {
325
387
  Also, if we are deleting the polling island and the merged_to field is
326
388
  non-empty, we should remove a ref to the merged_to polling island
327
389
  */
328
- switch (gpr_atm_full_fetch_add(&pi->ref_count, -1)) {
329
- case 2: /* last external ref: the only one now owned is by the workqueue */
330
- GRPC_WORKQUEUE_UNREF(exec_ctx, pi->workqueue, "polling_island");
331
- break;
332
- case 1: {
333
- polling_island *next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
334
- polling_island_delete(exec_ctx, pi);
335
- if (next != NULL) {
336
- PI_UNREF(exec_ctx, next, "pi_delete"); /* Recursive call */
337
- }
338
- break;
390
+ if (1 == gpr_atm_full_fetch_add(&pi->ref_count, -1)) {
391
+ polling_island *next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
392
+ polling_island_delete(exec_ctx, pi);
393
+ if (next != NULL) {
394
+ PI_UNREF(exec_ctx, next, "pi_delete"); /* Recursive call */
339
395
  }
340
- case 0:
341
- GPR_UNREACHABLE_CODE(return );
342
396
  }
343
397
  }
344
398
 
@@ -404,9 +458,8 @@ static void polling_island_add_wakeup_fd_locked(polling_island *pi,
404
458
  gpr_asprintf(&err_msg,
405
459
  "epoll_ctl (epoll_fd: %d) add wakeup fd: %d failed with "
406
460
  "error: %d (%s)",
407
- pi->epoll_fd,
408
- GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), errno,
409
- strerror(errno));
461
+ pi->epoll_fd, GRPC_WAKEUP_FD_GET_READ_FD(&global_wakeup_fd),
462
+ errno, strerror(errno));
410
463
  append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
411
464
  gpr_free(err_msg);
412
465
  }
@@ -482,16 +535,26 @@ static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx,
482
535
  *error = GRPC_ERROR_NONE;
483
536
 
484
537
  pi = gpr_malloc(sizeof(*pi));
538
+ pi->workqueue_scheduler.vtable = &workqueue_scheduler_vtable;
485
539
  gpr_mu_init(&pi->mu);
486
540
  pi->fd_cnt = 0;
487
541
  pi->fd_capacity = 0;
488
542
  pi->fds = NULL;
489
543
  pi->epoll_fd = -1;
490
- pi->workqueue = NULL;
544
+
545
+ gpr_mu_init(&pi->workqueue_read_mu);
546
+ gpr_mpscq_init(&pi->workqueue_items);
547
+ gpr_atm_rel_store(&pi->workqueue_item_count, 0);
491
548
 
492
549
  gpr_atm_rel_store(&pi->ref_count, 0);
550
+ gpr_atm_rel_store(&pi->poller_count, 0);
493
551
  gpr_atm_rel_store(&pi->merged_to, (gpr_atm)NULL);
494
552
 
553
+ if (!append_error(error, grpc_wakeup_fd_init(&pi->workqueue_wakeup_fd),
554
+ err_desc)) {
555
+ goto done;
556
+ }
557
+
495
558
  pi->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
496
559
 
497
560
  if (pi->epoll_fd < 0) {
@@ -499,27 +562,15 @@ static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx,
499
562
  goto done;
500
563
  }
501
564
 
502
- polling_island_add_wakeup_fd_locked(pi, &grpc_global_wakeup_fd, error);
565
+ polling_island_add_wakeup_fd_locked(pi, &global_wakeup_fd, error);
566
+ polling_island_add_wakeup_fd_locked(pi, &pi->workqueue_wakeup_fd, error);
503
567
 
504
568
  if (initial_fd != NULL) {
505
569
  polling_island_add_fds_locked(pi, &initial_fd, 1, true, error);
506
570
  }
507
571
 
508
- if (append_error(error, grpc_workqueue_create(exec_ctx, &pi->workqueue),
509
- err_desc) &&
510
- *error == GRPC_ERROR_NONE) {
511
- polling_island_add_fds_locked(pi, &pi->workqueue->wakeup_read_fd, 1, true,
512
- error);
513
- GPR_ASSERT(pi->workqueue->wakeup_read_fd->polling_island == NULL);
514
- pi->workqueue->wakeup_read_fd->polling_island = pi;
515
- PI_ADD_REF(pi, "fd");
516
- }
517
-
518
572
  done:
519
573
  if (*error != GRPC_ERROR_NONE) {
520
- if (pi->workqueue != NULL) {
521
- GRPC_WORKQUEUE_UNREF(exec_ctx, pi->workqueue, "polling_island");
522
- }
523
574
  polling_island_delete(exec_ctx, pi);
524
575
  pi = NULL;
525
576
  }
@@ -532,7 +583,11 @@ static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi) {
532
583
  if (pi->epoll_fd >= 0) {
533
584
  close(pi->epoll_fd);
534
585
  }
586
+ GPR_ASSERT(gpr_atm_no_barrier_load(&pi->workqueue_item_count) == 0);
587
+ gpr_mu_destroy(&pi->workqueue_read_mu);
588
+ gpr_mpscq_destroy(&pi->workqueue_items);
535
589
  gpr_mu_destroy(&pi->mu);
590
+ grpc_wakeup_fd_destroy(&pi->workqueue_wakeup_fd);
536
591
  gpr_free(pi->fds);
537
592
  gpr_free(pi);
538
593
  }
@@ -677,6 +732,45 @@ static void polling_island_unlock_pair(polling_island *p, polling_island *q) {
677
732
  }
678
733
  }
679
734
 
735
+ static void workqueue_maybe_wakeup(polling_island *pi) {
736
+ /* If this thread is the current poller, then it may be that it's about to
737
+ decrement the current poller count, so we need to look past this thread */
738
+ bool is_current_poller = (g_current_thread_polling_island == pi);
739
+ gpr_atm min_current_pollers_for_wakeup = is_current_poller ? 1 : 0;
740
+ gpr_atm current_pollers = gpr_atm_no_barrier_load(&pi->poller_count);
741
+ /* Only issue a wakeup if it's likely that some poller could come in and take
742
+ it right now. Note that since we do an anticipatory mpscq_pop every poll
743
+ loop, it's ok if we miss the wakeup here, as we'll get the work item when
744
+ the next poller enters anyway. */
745
+ if (current_pollers > min_current_pollers_for_wakeup) {
746
+ GRPC_LOG_IF_ERROR("workqueue_wakeup_fd",
747
+ grpc_wakeup_fd_wakeup(&pi->workqueue_wakeup_fd));
748
+ }
749
+ }
750
+
751
+ static void workqueue_move_items_to_parent(polling_island *q) {
752
+ polling_island *p = (polling_island *)gpr_atm_no_barrier_load(&q->merged_to);
753
+ if (p == NULL) {
754
+ return;
755
+ }
756
+ gpr_mu_lock(&q->workqueue_read_mu);
757
+ int num_added = 0;
758
+ while (gpr_atm_no_barrier_load(&q->workqueue_item_count) > 0) {
759
+ gpr_mpscq_node *n = gpr_mpscq_pop(&q->workqueue_items);
760
+ if (n != NULL) {
761
+ gpr_atm_no_barrier_fetch_add(&q->workqueue_item_count, -1);
762
+ gpr_atm_no_barrier_fetch_add(&p->workqueue_item_count, 1);
763
+ gpr_mpscq_push(&p->workqueue_items, n);
764
+ num_added++;
765
+ }
766
+ }
767
+ gpr_mu_unlock(&q->workqueue_read_mu);
768
+ if (num_added > 0) {
769
+ workqueue_maybe_wakeup(p);
770
+ }
771
+ workqueue_move_items_to_parent(p);
772
+ }
773
+
680
774
  static polling_island *polling_island_merge(polling_island *p,
681
775
  polling_island *q,
682
776
  grpc_error **error) {
@@ -701,6 +795,8 @@ static polling_island *polling_island_merge(polling_island *p,
701
795
  /* Add the 'merged_to' link from p --> q */
702
796
  gpr_atm_rel_store(&p->merged_to, (gpr_atm)q);
703
797
  PI_ADD_REF(q, "pi_merge"); /* To account for the new incoming ref from p */
798
+
799
+ workqueue_move_items_to_parent(p);
704
800
  }
705
801
  /* else if p == q, nothing needs to be done */
706
802
 
@@ -711,6 +807,32 @@ static polling_island *polling_island_merge(polling_island *p,
711
807
  return q;
712
808
  }
713
809
 
810
+ static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
811
+ grpc_error *error) {
812
+ GPR_TIMER_BEGIN("workqueue.enqueue", 0);
813
+ grpc_workqueue *workqueue = (grpc_workqueue *)closure->scheduler;
814
+ /* take a ref to the workqueue: otherwise it can happen that whatever events
815
+ * this kicks off ends up destroying the workqueue before this function
816
+ * completes */
817
+ GRPC_WORKQUEUE_REF(workqueue, "enqueue");
818
+ polling_island *pi = (polling_island *)workqueue;
819
+ gpr_atm last = gpr_atm_no_barrier_fetch_add(&pi->workqueue_item_count, 1);
820
+ closure->error_data.error = error;
821
+ gpr_mpscq_push(&pi->workqueue_items, &closure->next_data.atm_next);
822
+ if (last == 0) {
823
+ workqueue_maybe_wakeup(pi);
824
+ }
825
+ workqueue_move_items_to_parent(pi);
826
+ GRPC_WORKQUEUE_UNREF(exec_ctx, workqueue, "enqueue");
827
+ GPR_TIMER_END("workqueue.enqueue", 0);
828
+ }
829
+
830
+ static grpc_closure_scheduler *workqueue_scheduler(grpc_workqueue *workqueue) {
831
+ polling_island *pi = (polling_island *)workqueue;
832
+ return workqueue == NULL ? grpc_schedule_on_exec_ctx
833
+ : &pi->workqueue_scheduler;
834
+ }
835
+
714
836
  static grpc_error *polling_island_global_init() {
715
837
  grpc_error *error = GRPC_ERROR_NONE;
716
838
 
@@ -748,11 +870,6 @@ static void polling_island_global_shutdown() {
748
870
  * alarm 'epoch'). This wakeup_fd gives us something to alert on when such a
749
871
  * case occurs. */
750
872
 
751
- /* TODO: sreek: Right now, this wakes up all pollers. In future we should make
752
- * sure to wake up one polling thread (which can wake up other threads if
753
- * needed) */
754
- grpc_wakeup_fd grpc_global_wakeup_fd;
755
-
756
873
  static grpc_fd *fd_freelist = NULL;
757
874
  static gpr_mu fd_freelist_mu;
758
875
 
@@ -821,7 +938,7 @@ static void fd_global_shutdown(void) {
821
938
  while (fd_freelist != NULL) {
822
939
  grpc_fd *fd = fd_freelist;
823
940
  fd_freelist = fd_freelist->freelist_next;
824
- gpr_mu_destroy(&fd->mu);
941
+ gpr_mu_destroy(&fd->po.mu);
825
942
  gpr_free(fd);
826
943
  }
827
944
  gpr_mu_destroy(&fd_freelist_mu);
@@ -839,13 +956,17 @@ static grpc_fd *fd_create(int fd, const char *name) {
839
956
 
840
957
  if (new_fd == NULL) {
841
958
  new_fd = gpr_malloc(sizeof(grpc_fd));
842
- gpr_mu_init(&new_fd->mu);
959
+ gpr_mu_init(&new_fd->po.mu);
843
960
  }
844
961
 
845
- /* Note: It is not really needed to get the new_fd->mu lock here. If this is a
846
- newly created fd (or an fd we got from the freelist), no one else would be
847
- holding a lock to it anyway. */
848
- gpr_mu_lock(&new_fd->mu);
962
+ /* Note: It is not really needed to get the new_fd->po.mu lock here. If this
963
+ * is a newly created fd (or an fd we got from the freelist), no one else
964
+ * would be holding a lock to it anyway. */
965
+ gpr_mu_lock(&new_fd->po.mu);
966
+ new_fd->po.pi = NULL;
967
+ #ifdef PO_DEBUG
968
+ new_fd->po.obj_type = POLL_OBJ_FD;
969
+ #endif
849
970
 
850
971
  gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
851
972
  new_fd->fd = fd;
@@ -853,12 +974,11 @@ static grpc_fd *fd_create(int fd, const char *name) {
853
974
  new_fd->orphaned = false;
854
975
  new_fd->read_closure = CLOSURE_NOT_READY;
855
976
  new_fd->write_closure = CLOSURE_NOT_READY;
856
- new_fd->polling_island = NULL;
857
977
  new_fd->freelist_next = NULL;
858
978
  new_fd->on_done_closure = NULL;
859
979
  new_fd->read_notifier_pollset = NULL;
860
980
 
861
- gpr_mu_unlock(&new_fd->mu);
981
+ gpr_mu_unlock(&new_fd->po.mu);
862
982
 
863
983
  char *fd_name;
864
984
  gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
@@ -870,17 +990,13 @@ static grpc_fd *fd_create(int fd, const char *name) {
870
990
  return new_fd;
871
991
  }
872
992
 
873
- static bool fd_is_orphaned(grpc_fd *fd) {
874
- return (gpr_atm_acq_load(&fd->refst) & 1) == 0;
875
- }
876
-
877
993
  static int fd_wrapped_fd(grpc_fd *fd) {
878
994
  int ret_fd = -1;
879
- gpr_mu_lock(&fd->mu);
995
+ gpr_mu_lock(&fd->po.mu);
880
996
  if (!fd->orphaned) {
881
997
  ret_fd = fd->fd;
882
998
  }
883
- gpr_mu_unlock(&fd->mu);
999
+ gpr_mu_unlock(&fd->po.mu);
884
1000
 
885
1001
  return ret_fd;
886
1002
  }
@@ -892,7 +1008,7 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
892
1008
  grpc_error *error = GRPC_ERROR_NONE;
893
1009
  polling_island *unref_pi = NULL;
894
1010
 
895
- gpr_mu_lock(&fd->mu);
1011
+ gpr_mu_lock(&fd->po.mu);
896
1012
  fd->on_done_closure = on_done;
897
1013
 
898
1014
  /* If release_fd is not NULL, we should be relinquishing control of the file
@@ -912,24 +1028,24 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
912
1028
 
913
1029
  /* Remove the fd from the polling island:
914
1030
  - Get a lock on the latest polling island (i.e the last island in the
915
- linked list pointed by fd->polling_island). This is the island that
1031
+ linked list pointed by fd->po.pi). This is the island that
916
1032
  would actually contain the fd
917
1033
  - Remove the fd from the latest polling island
918
1034
  - Unlock the latest polling island
919
- - Set fd->polling_island to NULL (but remove the ref on the polling island
1035
+ - Set fd->po.pi to NULL (but remove the ref on the polling island
920
1036
  before doing this.) */
921
- if (fd->polling_island != NULL) {
922
- polling_island *pi_latest = polling_island_lock(fd->polling_island);
1037
+ if (fd->po.pi != NULL) {
1038
+ polling_island *pi_latest = polling_island_lock(fd->po.pi);
923
1039
  polling_island_remove_fd_locked(pi_latest, fd, is_fd_closed, &error);
924
1040
  gpr_mu_unlock(&pi_latest->mu);
925
1041
 
926
- unref_pi = fd->polling_island;
927
- fd->polling_island = NULL;
1042
+ unref_pi = fd->po.pi;
1043
+ fd->po.pi = NULL;
928
1044
  }
929
1045
 
930
- grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, error, NULL);
1046
+ grpc_closure_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_REF(error));
931
1047
 
932
- gpr_mu_unlock(&fd->mu);
1048
+ gpr_mu_unlock(&fd->po.mu);
933
1049
  UNREF_BY(fd, 2, reason); /* Drop the reference */
934
1050
  if (unref_pi != NULL) {
935
1051
  /* Unref stale polling island here, outside the fd lock above.
@@ -939,6 +1055,7 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
939
1055
  PI_UNREF(exec_ctx, unref_pi, "fd_orphan");
940
1056
  }
941
1057
  GRPC_LOG_IF_ERROR("fd_orphan", GRPC_ERROR_REF(error));
1058
+ GRPC_ERROR_UNREF(error);
942
1059
  }
943
1060
 
944
1061
  static grpc_error *fd_shutdown_error(bool shutdown) {
@@ -952,16 +1069,14 @@ static grpc_error *fd_shutdown_error(bool shutdown) {
952
1069
  static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
953
1070
  grpc_closure **st, grpc_closure *closure) {
954
1071
  if (fd->shutdown) {
955
- grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"),
956
- NULL);
1072
+ grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"));
957
1073
  } else if (*st == CLOSURE_NOT_READY) {
958
1074
  /* not ready ==> switch to a waiting state by setting the closure */
959
1075
  *st = closure;
960
1076
  } else if (*st == CLOSURE_READY) {
961
1077
  /* already ready ==> queue the closure to run immediately */
962
1078
  *st = CLOSURE_NOT_READY;
963
- grpc_exec_ctx_sched(exec_ctx, closure, fd_shutdown_error(fd->shutdown),
964
- NULL);
1079
+ grpc_closure_sched(exec_ctx, closure, fd_shutdown_error(fd->shutdown));
965
1080
  } else {
966
1081
  /* upcallptr was set to a different closure. This is an error! */
967
1082
  gpr_log(GPR_ERROR,
@@ -983,7 +1098,7 @@ static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
983
1098
  return 0;
984
1099
  } else {
985
1100
  /* waiting ==> queue closure */
986
- grpc_exec_ctx_sched(exec_ctx, *st, fd_shutdown_error(fd->shutdown), NULL);
1101
+ grpc_closure_sched(exec_ctx, *st, fd_shutdown_error(fd->shutdown));
987
1102
  *st = CLOSURE_NOT_READY;
988
1103
  return 1;
989
1104
  }
@@ -993,23 +1108,23 @@ static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
993
1108
  grpc_fd *fd) {
994
1109
  grpc_pollset *notifier = NULL;
995
1110
 
996
- gpr_mu_lock(&fd->mu);
1111
+ gpr_mu_lock(&fd->po.mu);
997
1112
  notifier = fd->read_notifier_pollset;
998
- gpr_mu_unlock(&fd->mu);
1113
+ gpr_mu_unlock(&fd->po.mu);
999
1114
 
1000
1115
  return notifier;
1001
1116
  }
1002
1117
 
1003
1118
  static bool fd_is_shutdown(grpc_fd *fd) {
1004
- gpr_mu_lock(&fd->mu);
1119
+ gpr_mu_lock(&fd->po.mu);
1005
1120
  const bool r = fd->shutdown;
1006
- gpr_mu_unlock(&fd->mu);
1121
+ gpr_mu_unlock(&fd->po.mu);
1007
1122
  return r;
1008
1123
  }
1009
1124
 
1010
1125
  /* Might be called multiple times */
1011
1126
  static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
1012
- gpr_mu_lock(&fd->mu);
1127
+ gpr_mu_lock(&fd->po.mu);
1013
1128
  /* Do the actual shutdown only once */
1014
1129
  if (!fd->shutdown) {
1015
1130
  fd->shutdown = true;
@@ -1020,31 +1135,28 @@ static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
1020
1135
  set_ready_locked(exec_ctx, fd, &fd->read_closure);
1021
1136
  set_ready_locked(exec_ctx, fd, &fd->write_closure);
1022
1137
  }
1023
- gpr_mu_unlock(&fd->mu);
1138
+ gpr_mu_unlock(&fd->po.mu);
1024
1139
  }
1025
1140
 
1026
1141
  static void fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1027
1142
  grpc_closure *closure) {
1028
- gpr_mu_lock(&fd->mu);
1143
+ gpr_mu_lock(&fd->po.mu);
1029
1144
  notify_on_locked(exec_ctx, fd, &fd->read_closure, closure);
1030
- gpr_mu_unlock(&fd->mu);
1145
+ gpr_mu_unlock(&fd->po.mu);
1031
1146
  }
1032
1147
 
1033
1148
  static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1034
1149
  grpc_closure *closure) {
1035
- gpr_mu_lock(&fd->mu);
1150
+ gpr_mu_lock(&fd->po.mu);
1036
1151
  notify_on_locked(exec_ctx, fd, &fd->write_closure, closure);
1037
- gpr_mu_unlock(&fd->mu);
1152
+ gpr_mu_unlock(&fd->po.mu);
1038
1153
  }
1039
1154
 
1040
1155
  static grpc_workqueue *fd_get_workqueue(grpc_fd *fd) {
1041
- gpr_mu_lock(&fd->mu);
1042
- grpc_workqueue *workqueue = NULL;
1043
- if (fd->polling_island != NULL) {
1044
- workqueue =
1045
- GRPC_WORKQUEUE_REF(fd->polling_island->workqueue, "get_workqueue");
1046
- }
1047
- gpr_mu_unlock(&fd->mu);
1156
+ gpr_mu_lock(&fd->po.mu);
1157
+ grpc_workqueue *workqueue =
1158
+ GRPC_WORKQUEUE_REF((grpc_workqueue *)fd->po.pi, "fd_get_workqueue");
1159
+ gpr_mu_unlock(&fd->po.mu);
1048
1160
  return workqueue;
1049
1161
  }
1050
1162
 
@@ -1069,11 +1181,11 @@ static grpc_error *pollset_global_init(void) {
1069
1181
  gpr_tls_init(&g_current_thread_pollset);
1070
1182
  gpr_tls_init(&g_current_thread_worker);
1071
1183
  poller_kick_init();
1072
- return grpc_wakeup_fd_init(&grpc_global_wakeup_fd);
1184
+ return grpc_wakeup_fd_init(&global_wakeup_fd);
1073
1185
  }
1074
1186
 
1075
1187
  static void pollset_global_shutdown(void) {
1076
- grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd);
1188
+ grpc_wakeup_fd_destroy(&global_wakeup_fd);
1077
1189
  gpr_tls_destroy(&g_current_thread_pollset);
1078
1190
  gpr_tls_destroy(&g_current_thread_worker);
1079
1191
  }
@@ -1180,12 +1292,16 @@ static grpc_error *pollset_kick(grpc_pollset *p,
1180
1292
  }
1181
1293
 
1182
1294
  static grpc_error *kick_poller(void) {
1183
- return grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd);
1295
+ return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
1184
1296
  }
1185
1297
 
1186
1298
  static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
1187
- gpr_mu_init(&pollset->mu);
1188
- *mu = &pollset->mu;
1299
+ gpr_mu_init(&pollset->po.mu);
1300
+ *mu = &pollset->po.mu;
1301
+ pollset->po.pi = NULL;
1302
+ #ifdef PO_DEBUG
1303
+ pollset->po.obj_type = POLL_OBJ_POLLSET;
1304
+ #endif
1189
1305
 
1190
1306
  pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker;
1191
1307
  pollset->kicked_without_pollers = false;
@@ -1193,8 +1309,6 @@ static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
1193
1309
  pollset->shutting_down = false;
1194
1310
  pollset->finish_shutdown_called = false;
1195
1311
  pollset->shutdown_done = NULL;
1196
-
1197
- pollset->polling_island = NULL;
1198
1312
  }
1199
1313
 
1200
1314
  /* Convert a timespec to milliseconds:
@@ -1224,26 +1338,26 @@ static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
1224
1338
 
1225
1339
  static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1226
1340
  grpc_pollset *notifier) {
1227
- /* Need the fd->mu since we might be racing with fd_notify_on_read */
1228
- gpr_mu_lock(&fd->mu);
1341
+ /* Need the fd->po.mu since we might be racing with fd_notify_on_read */
1342
+ gpr_mu_lock(&fd->po.mu);
1229
1343
  set_ready_locked(exec_ctx, fd, &fd->read_closure);
1230
1344
  fd->read_notifier_pollset = notifier;
1231
- gpr_mu_unlock(&fd->mu);
1345
+ gpr_mu_unlock(&fd->po.mu);
1232
1346
  }
1233
1347
 
1234
1348
  static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
1235
- /* Need the fd->mu since we might be racing with fd_notify_on_write */
1236
- gpr_mu_lock(&fd->mu);
1349
+ /* Need the fd->po.mu since we might be racing with fd_notify_on_write */
1350
+ gpr_mu_lock(&fd->po.mu);
1237
1351
  set_ready_locked(exec_ctx, fd, &fd->write_closure);
1238
- gpr_mu_unlock(&fd->mu);
1352
+ gpr_mu_unlock(&fd->po.mu);
1239
1353
  }
1240
1354
 
1241
1355
  static void pollset_release_polling_island(grpc_exec_ctx *exec_ctx,
1242
1356
  grpc_pollset *ps, char *reason) {
1243
- if (ps->polling_island != NULL) {
1244
- PI_UNREF(exec_ctx, ps->polling_island, reason);
1357
+ if (ps->po.pi != NULL) {
1358
+ PI_UNREF(exec_ctx, ps->po.pi, reason);
1245
1359
  }
1246
- ps->polling_island = NULL;
1360
+ ps->po.pi = NULL;
1247
1361
  }
1248
1362
 
1249
1363
  static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx,
@@ -1253,12 +1367,12 @@ static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx,
1253
1367
 
1254
1368
  pollset->finish_shutdown_called = true;
1255
1369
 
1256
- /* Release the ref and set pollset->polling_island to NULL */
1370
+ /* Release the ref and set pollset->po.pi to NULL */
1257
1371
  pollset_release_polling_island(exec_ctx, pollset, "ps_shutdown");
1258
- grpc_exec_ctx_sched(exec_ctx, pollset->shutdown_done, GRPC_ERROR_NONE, NULL);
1372
+ grpc_closure_sched(exec_ctx, pollset->shutdown_done, GRPC_ERROR_NONE);
1259
1373
  }
1260
1374
 
1261
- /* pollset->mu lock must be held by the caller before calling this */
1375
+ /* pollset->po.mu lock must be held by the caller before calling this */
1262
1376
  static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1263
1377
  grpc_closure *closure) {
1264
1378
  GPR_TIMER_BEGIN("pollset_shutdown", 0);
@@ -1283,7 +1397,7 @@ static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1283
1397
  * here */
1284
1398
  static void pollset_destroy(grpc_pollset *pollset) {
1285
1399
  GPR_ASSERT(!pollset_has_workers(pollset));
1286
- gpr_mu_destroy(&pollset->mu);
1400
+ gpr_mu_destroy(&pollset->po.mu);
1287
1401
  }
1288
1402
 
1289
1403
  static void pollset_reset(grpc_pollset *pollset) {
@@ -1293,10 +1407,34 @@ static void pollset_reset(grpc_pollset *pollset) {
1293
1407
  pollset->finish_shutdown_called = false;
1294
1408
  pollset->kicked_without_pollers = false;
1295
1409
  pollset->shutdown_done = NULL;
1296
- GPR_ASSERT(pollset->polling_island == NULL);
1410
+ GPR_ASSERT(pollset->po.pi == NULL);
1297
1411
  }
1298
1412
 
1299
- #define GRPC_EPOLL_MAX_EVENTS 1000
1413
+ static bool maybe_do_workqueue_work(grpc_exec_ctx *exec_ctx,
1414
+ polling_island *pi) {
1415
+ if (gpr_mu_trylock(&pi->workqueue_read_mu)) {
1416
+ gpr_mpscq_node *n = gpr_mpscq_pop(&pi->workqueue_items);
1417
+ gpr_mu_unlock(&pi->workqueue_read_mu);
1418
+ if (n != NULL) {
1419
+ if (gpr_atm_full_fetch_add(&pi->workqueue_item_count, -1) > 1) {
1420
+ workqueue_maybe_wakeup(pi);
1421
+ }
1422
+ grpc_closure *c = (grpc_closure *)n;
1423
+ grpc_error *error = c->error_data.error;
1424
+ c->cb(exec_ctx, c->cb_arg, error);
1425
+ GRPC_ERROR_UNREF(error);
1426
+ return true;
1427
+ } else if (gpr_atm_no_barrier_load(&pi->workqueue_item_count) > 0) {
1428
+ /* n == NULL might mean there's work but it's not available to be popped
1429
+ * yet - try to ensure another workqueue wakes up to check shortly if so
1430
+ */
1431
+ workqueue_maybe_wakeup(pi);
1432
+ }
1433
+ }
1434
+ return false;
1435
+ }
1436
+
1437
+ #define GRPC_EPOLL_MAX_EVENTS 100
1300
1438
  /* Note: sig_mask contains the signal mask to use *during* epoll_wait() */
1301
1439
  static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
1302
1440
  grpc_pollset *pollset,
@@ -1311,7 +1449,7 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
1311
1449
  GPR_TIMER_BEGIN("pollset_work_and_unlock", 0);
1312
1450
 
1313
1451
  /* We need to get the epoll_fd to wait on. The epoll_fd is in inside the
1314
- latest polling island pointed by pollset->polling_island.
1452
+ latest polling island pointed by pollset->po.pi
1315
1453
 
1316
1454
  Since epoll_fd is immutable, we can read it without obtaining the polling
1317
1455
  island lock. There is however a possibility that the polling island (from
@@ -1320,40 +1458,48 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
1320
1458
  right-away from epoll_wait() and pick up the latest polling_island the next
1321
1459
  this function (i.e pollset_work_and_unlock()) is called */
1322
1460
 
1323
- if (pollset->polling_island == NULL) {
1324
- pollset->polling_island = polling_island_create(exec_ctx, NULL, error);
1325
- if (pollset->polling_island == NULL) {
1461
+ if (pollset->po.pi == NULL) {
1462
+ pollset->po.pi = polling_island_create(exec_ctx, NULL, error);
1463
+ if (pollset->po.pi == NULL) {
1326
1464
  GPR_TIMER_END("pollset_work_and_unlock", 0);
1327
1465
  return; /* Fatal error. We cannot continue */
1328
1466
  }
1329
1467
 
1330
- PI_ADD_REF(pollset->polling_island, "ps");
1468
+ PI_ADD_REF(pollset->po.pi, "ps");
1331
1469
  GRPC_POLLING_TRACE("pollset_work: pollset: %p created new pi: %p",
1332
- (void *)pollset, (void *)pollset->polling_island);
1470
+ (void *)pollset, (void *)pollset->po.pi);
1333
1471
  }
1334
1472
 
1335
- pi = polling_island_maybe_get_latest(pollset->polling_island);
1473
+ pi = polling_island_maybe_get_latest(pollset->po.pi);
1336
1474
  epoll_fd = pi->epoll_fd;
1337
1475
 
1338
- /* Update the pollset->polling_island since the island being pointed by
1339
- pollset->polling_island maybe older than the one pointed by pi) */
1340
- if (pollset->polling_island != pi) {
1476
+ /* Update the pollset->po.pi since the island being pointed by
1477
+ pollset->po.pi maybe older than the one pointed by pi) */
1478
+ if (pollset->po.pi != pi) {
1341
1479
  /* Always do PI_ADD_REF before PI_UNREF because PI_UNREF may cause the
1342
1480
  polling island to be deleted */
1343
1481
  PI_ADD_REF(pi, "ps");
1344
- PI_UNREF(exec_ctx, pollset->polling_island, "ps");
1345
- pollset->polling_island = pi;
1482
+ PI_UNREF(exec_ctx, pollset->po.pi, "ps");
1483
+ pollset->po.pi = pi;
1346
1484
  }
1347
1485
 
1348
1486
  /* Add an extra ref so that the island does not get destroyed (which means
1349
1487
  the epoll_fd won't be closed) while we are are doing an epoll_wait() on the
1350
1488
  epoll_fd */
1351
1489
  PI_ADD_REF(pi, "ps_work");
1352
- gpr_mu_unlock(&pollset->mu);
1490
+ gpr_mu_unlock(&pollset->po.mu);
1491
+
1492
+ /* If we get some workqueue work to do, it might end up completing an item on
1493
+ the completion queue, so there's no need to poll... so we skip that and
1494
+ redo the complete loop to verify */
1495
+ if (!maybe_do_workqueue_work(exec_ctx, pi)) {
1496
+ gpr_atm_no_barrier_fetch_add(&pi->poller_count, 1);
1497
+ g_current_thread_polling_island = pi;
1353
1498
 
1354
- do {
1499
+ GRPC_SCHEDULING_START_BLOCKING_REGION;
1355
1500
  ep_rv = epoll_pwait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, timeout_ms,
1356
1501
  sig_mask);
1502
+ GRPC_SCHEDULING_END_BLOCKING_REGION;
1357
1503
  if (ep_rv < 0) {
1358
1504
  if (errno != EINTR) {
1359
1505
  gpr_asprintf(&err_msg,
@@ -1377,10 +1523,13 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
1377
1523
 
1378
1524
  for (int i = 0; i < ep_rv; ++i) {
1379
1525
  void *data_ptr = ep_ev[i].data.ptr;
1380
- if (data_ptr == &grpc_global_wakeup_fd) {
1381
- append_error(error,
1382
- grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd),
1526
+ if (data_ptr == &global_wakeup_fd) {
1527
+ append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
1383
1528
  err_desc);
1529
+ } else if (data_ptr == &pi->workqueue_wakeup_fd) {
1530
+ append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
1531
+ err_desc);
1532
+ maybe_do_workqueue_work(exec_ctx, pi);
1384
1533
  } else if (data_ptr == &polling_island_wakeup_fd) {
1385
1534
  GRPC_POLLING_TRACE(
1386
1535
  "pollset_work: pollset: %p, worker: %p polling island (epoll_fd: "
@@ -1403,22 +1552,25 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
1403
1552
  }
1404
1553
  }
1405
1554
  }
1406
- } while (ep_rv == GRPC_EPOLL_MAX_EVENTS);
1555
+
1556
+ g_current_thread_polling_island = NULL;
1557
+ gpr_atm_no_barrier_fetch_add(&pi->poller_count, -1);
1558
+ }
1407
1559
 
1408
1560
  GPR_ASSERT(pi != NULL);
1409
1561
 
1410
1562
  /* Before leaving, release the extra ref we added to the polling island. It
1411
- is important to use "pi" here (i.e our old copy of pollset->polling_island
1563
+ is important to use "pi" here (i.e our old copy of pollset->po.pi
1412
1564
  that we got before releasing the polling island lock). This is because
1413
- pollset->polling_island pointer might get udpated in other parts of the
1565
+ pollset->po.pi pointer might get udpated in other parts of the
1414
1566
  code when there is an island merge while we are doing epoll_wait() above */
1415
1567
  PI_UNREF(exec_ctx, pi, "ps_work");
1416
1568
 
1417
1569
  GPR_TIMER_END("pollset_work_and_unlock", 0);
1418
1570
  }
1419
1571
 
1420
- /* pollset->mu lock must be held by the caller before calling this.
1421
- The function pollset_work() may temporarily release the lock (pollset->mu)
1572
+ /* pollset->po.mu lock must be held by the caller before calling this.
1573
+ The function pollset_work() may temporarily release the lock (pollset->po.mu)
1422
1574
  during the course of its execution but it will always re-acquire the lock and
1423
1575
  ensure that it is held by the time the function returns */
1424
1576
  static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
@@ -1488,7 +1640,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1488
1640
  &g_orig_sigmask, &error);
1489
1641
  grpc_exec_ctx_flush(exec_ctx);
1490
1642
 
1491
- gpr_mu_lock(&pollset->mu);
1643
+ gpr_mu_lock(&pollset->po.mu);
1492
1644
 
1493
1645
  /* Note: There is no need to reset worker.is_kicked to 0 since we are no
1494
1646
  longer going to use this worker */
@@ -1508,9 +1660,9 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1508
1660
  GPR_TIMER_MARK("pollset_work.finish_shutdown_locked", 0);
1509
1661
  finish_shutdown_locked(exec_ctx, pollset);
1510
1662
 
1511
- gpr_mu_unlock(&pollset->mu);
1663
+ gpr_mu_unlock(&pollset->po.mu);
1512
1664
  grpc_exec_ctx_flush(exec_ctx);
1513
- gpr_mu_lock(&pollset->mu);
1665
+ gpr_mu_lock(&pollset->po.mu);
1514
1666
  }
1515
1667
 
1516
1668
  *worker_hdl = NULL;
@@ -1524,120 +1676,160 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1524
1676
  return error;
1525
1677
  }
1526
1678
 
1527
- static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1528
- grpc_fd *fd) {
1529
- grpc_error *error = GRPC_ERROR_NONE;
1679
+ static void add_poll_object(grpc_exec_ctx *exec_ctx, poll_obj *bag,
1680
+ poll_obj_type bag_type, poll_obj *item,
1681
+ poll_obj_type item_type) {
1682
+ GPR_TIMER_BEGIN("add_poll_object", 0);
1530
1683
 
1531
- gpr_mu_lock(&pollset->mu);
1532
- gpr_mu_lock(&fd->mu);
1684
+ #ifdef PO_DEBUG
1685
+ GPR_ASSERT(item->obj_type == item_type);
1686
+ GPR_ASSERT(bag->obj_type == bag_type);
1687
+ #endif
1533
1688
 
1689
+ grpc_error *error = GRPC_ERROR_NONE;
1534
1690
  polling_island *pi_new = NULL;
1535
1691
 
1692
+ gpr_mu_lock(&bag->mu);
1693
+ gpr_mu_lock(&item->mu);
1694
+
1536
1695
  retry:
1537
- /* 1) If fd->polling_island and pollset->polling_island are both non-NULL and
1538
- * equal, do nothing.
1539
- * 2) If fd->polling_island and pollset->polling_island are both NULL, create
1540
- * a new polling island (with a refcount of 2) and make the polling_island
1541
- * fields in both fd and pollset to point to the new island
1542
- * 3) If one of fd->polling_island or pollset->polling_island is NULL, update
1543
- * the NULL polling_island field to point to the non-NULL polling_island
1544
- * field (ensure that the refcount on the polling island is incremented by
1545
- * 1 to account for the newly added reference)
1546
- * 4) Finally, if fd->polling_island and pollset->polling_island are non-NULL
1547
- * and different, merge both the polling islands and update the
1548
- * polling_island fields in both fd and pollset to point to the merged
1549
- * polling island.
1696
+ /*
1697
+ * 1) If item->pi and bag->pi are both non-NULL and equal, do nothing
1698
+ * 2) If item->pi and bag->pi are both NULL, create a new polling island (with
1699
+ * a refcount of 2) and point item->pi and bag->pi to the new island
1700
+ * 3) If exactly one of item->pi or bag->pi is NULL, update it to point to
1701
+ * the other's non-NULL pi
1702
+ * 4) Finally if item->pi and bag-pi are non-NULL and not-equal, merge the
1703
+ * polling islands and update item->pi and bag->pi to point to the new
1704
+ * island
1550
1705
  */
1551
1706
 
1552
- if (fd->orphaned) {
1553
- gpr_mu_unlock(&fd->mu);
1554
- gpr_mu_unlock(&pollset->mu);
1555
- /* early out */
1707
+ /* Early out if we are trying to add an 'fd' to a 'bag' but the fd is already
1708
+ * orphaned */
1709
+ if (item_type == POLL_OBJ_FD && (FD_FROM_PO(item))->orphaned) {
1710
+ gpr_mu_unlock(&item->mu);
1711
+ gpr_mu_unlock(&bag->mu);
1556
1712
  return;
1557
1713
  }
1558
1714
 
1559
- if (fd->polling_island == pollset->polling_island) {
1560
- pi_new = fd->polling_island;
1715
+ if (item->pi == bag->pi) {
1716
+ pi_new = item->pi;
1561
1717
  if (pi_new == NULL) {
1562
- /* Unlock before creating a new polling island: the polling island will
1563
- create a workqueue which creates a file descriptor, and holding an fd
1564
- lock here can eventually cause a loop to appear to TSAN (making it
1565
- unhappy). We don't think it's a real loop (there's an epoch point where
1566
- that loop possibility disappears), but the advantages of keeping TSAN
1567
- happy outweigh any performance advantage we might have by keeping the
1568
- lock held. */
1569
- gpr_mu_unlock(&fd->mu);
1570
- pi_new = polling_island_create(exec_ctx, fd, &error);
1571
- gpr_mu_lock(&fd->mu);
1572
- /* Need to reverify any assumptions made between the initial lock and
1573
- getting to this branch: if they've changed, we need to throw away our
1574
- work and figure things out again. */
1575
- if (fd->polling_island != NULL) {
1576
- GRPC_POLLING_TRACE(
1577
- "pollset_add_fd: Raced creating new polling island. pi_new: %p "
1578
- "(fd: %d, pollset: %p)",
1579
- (void *)pi_new, fd->fd, (void *)pollset);
1580
- PI_ADD_REF(pi_new, "dance_of_destruction");
1581
- PI_UNREF(exec_ctx, pi_new, "dance_of_destruction");
1582
- goto retry;
1718
+ /* GPR_ASSERT(item->pi == bag->pi == NULL) */
1719
+
1720
+ /* If we are adding an fd to a bag (i.e pollset or pollset_set), then
1721
+ * we need to do some extra work to make TSAN happy */
1722
+ if (item_type == POLL_OBJ_FD) {
1723
+ /* Unlock before creating a new polling island: the polling island will
1724
+ create a workqueue which creates a file descriptor, and holding an fd
1725
+ lock here can eventually cause a loop to appear to TSAN (making it
1726
+ unhappy). We don't think it's a real loop (there's an epoch point
1727
+ where that loop possibility disappears), but the advantages of
1728
+ keeping TSAN happy outweigh any performance advantage we might have
1729
+ by keeping the lock held. */
1730
+ gpr_mu_unlock(&item->mu);
1731
+ pi_new = polling_island_create(exec_ctx, FD_FROM_PO(item), &error);
1732
+ gpr_mu_lock(&item->mu);
1733
+
1734
+ /* Need to reverify any assumptions made between the initial lock and
1735
+ getting to this branch: if they've changed, we need to throw away our
1736
+ work and figure things out again. */
1737
+ if (item->pi != NULL) {
1738
+ GRPC_POLLING_TRACE(
1739
+ "add_poll_object: Raced creating new polling island. pi_new: %p "
1740
+ "(fd: %d, %s: %p)",
1741
+ (void *)pi_new, FD_FROM_PO(item)->fd, poll_obj_string(bag_type),
1742
+ (void *)bag);
1743
+ /* No need to lock 'pi_new' here since this is a new polling island
1744
+ * and no one has a reference to it yet */
1745
+ polling_island_remove_all_fds_locked(pi_new, true, &error);
1746
+
1747
+ /* Ref and unref so that the polling island gets deleted during unref
1748
+ */
1749
+ PI_ADD_REF(pi_new, "dance_of_destruction");
1750
+ PI_UNREF(exec_ctx, pi_new, "dance_of_destruction");
1751
+ goto retry;
1752
+ }
1583
1753
  } else {
1584
- GRPC_POLLING_TRACE(
1585
- "pollset_add_fd: Created new polling island. pi_new: %p (fd: %d, "
1586
- "pollset: %p)",
1587
- (void *)pi_new, fd->fd, (void *)pollset);
1754
+ pi_new = polling_island_create(exec_ctx, NULL, &error);
1588
1755
  }
1756
+
1757
+ GRPC_POLLING_TRACE(
1758
+ "add_poll_object: Created new polling island. pi_new: %p (%s: %p, "
1759
+ "%s: %p)",
1760
+ (void *)pi_new, poll_obj_string(item_type), (void *)item,
1761
+ poll_obj_string(bag_type), (void *)bag);
1762
+ } else {
1763
+ GRPC_POLLING_TRACE(
1764
+ "add_poll_object: Same polling island. pi: %p (%s, %s)",
1765
+ (void *)pi_new, poll_obj_string(item_type),
1766
+ poll_obj_string(bag_type));
1767
+ }
1768
+ } else if (item->pi == NULL) {
1769
+ /* GPR_ASSERT(bag->pi != NULL) */
1770
+ /* Make pi_new point to latest pi*/
1771
+ pi_new = polling_island_lock(bag->pi);
1772
+
1773
+ if (item_type == POLL_OBJ_FD) {
1774
+ grpc_fd *fd = FD_FROM_PO(item);
1775
+ polling_island_add_fds_locked(pi_new, &fd, 1, true, &error);
1589
1776
  }
1590
- } else if (fd->polling_island == NULL) {
1591
- pi_new = polling_island_lock(pollset->polling_island);
1592
- polling_island_add_fds_locked(pi_new, &fd, 1, true, &error);
1593
- gpr_mu_unlock(&pi_new->mu);
1594
1777
 
1778
+ gpr_mu_unlock(&pi_new->mu);
1595
1779
  GRPC_POLLING_TRACE(
1596
- "pollset_add_fd: fd->pi was NULL. pi_new: %p (fd: %d, pollset: %p, "
1597
- "pollset->pi: %p)",
1598
- (void *)pi_new, fd->fd, (void *)pollset,
1599
- (void *)pollset->polling_island);
1600
- } else if (pollset->polling_island == NULL) {
1601
- pi_new = polling_island_lock(fd->polling_island);
1780
+ "add_poll_obj: item->pi was NULL. pi_new: %p (item(%s): %p, "
1781
+ "bag(%s): %p)",
1782
+ (void *)pi_new, poll_obj_string(item_type), (void *)item,
1783
+ poll_obj_string(bag_type), (void *)bag);
1784
+ } else if (bag->pi == NULL) {
1785
+ /* GPR_ASSERT(item->pi != NULL) */
1786
+ /* Make pi_new to point to latest pi */
1787
+ pi_new = polling_island_lock(item->pi);
1602
1788
  gpr_mu_unlock(&pi_new->mu);
1603
-
1604
1789
  GRPC_POLLING_TRACE(
1605
- "pollset_add_fd: pollset->pi was NULL. pi_new: %p (fd: %d, pollset: "
1606
- "%p, fd->pi: %p",
1607
- (void *)pi_new, fd->fd, (void *)pollset, (void *)fd->polling_island);
1790
+ "add_poll_obj: bag->pi was NULL. pi_new: %p (item(%s): %p, "
1791
+ "bag(%s): %p)",
1792
+ (void *)pi_new, poll_obj_string(item_type), (void *)item,
1793
+ poll_obj_string(bag_type), (void *)bag);
1608
1794
  } else {
1609
- pi_new = polling_island_merge(fd->polling_island, pollset->polling_island,
1610
- &error);
1795
+ pi_new = polling_island_merge(item->pi, bag->pi, &error);
1611
1796
  GRPC_POLLING_TRACE(
1612
- "pollset_add_fd: polling islands merged. pi_new: %p (fd: %d, pollset: "
1613
- "%p, fd->pi: %p, pollset->pi: %p)",
1614
- (void *)pi_new, fd->fd, (void *)pollset, (void *)fd->polling_island,
1615
- (void *)pollset->polling_island);
1797
+ "add_poll_obj: polling islands merged. pi_new: %p (item(%s): %p, "
1798
+ "bag(%s): %p)",
1799
+ (void *)pi_new, poll_obj_string(item_type), (void *)item,
1800
+ poll_obj_string(bag_type), (void *)bag);
1616
1801
  }
1617
1802
 
1618
- /* At this point, pi_new is the polling island that both fd->polling_island
1619
- and pollset->polling_island must be pointing to */
1803
+ /* At this point, pi_new is the polling island that both item->pi and bag->pi
1804
+ MUST be pointing to */
1620
1805
 
1621
- if (fd->polling_island != pi_new) {
1622
- PI_ADD_REF(pi_new, "fd");
1623
- if (fd->polling_island != NULL) {
1624
- PI_UNREF(exec_ctx, fd->polling_island, "fd");
1806
+ if (item->pi != pi_new) {
1807
+ PI_ADD_REF(pi_new, poll_obj_string(item_type));
1808
+ if (item->pi != NULL) {
1809
+ PI_UNREF(exec_ctx, item->pi, poll_obj_string(item_type));
1625
1810
  }
1626
- fd->polling_island = pi_new;
1811
+ item->pi = pi_new;
1627
1812
  }
1628
1813
 
1629
- if (pollset->polling_island != pi_new) {
1630
- PI_ADD_REF(pi_new, "ps");
1631
- if (pollset->polling_island != NULL) {
1632
- PI_UNREF(exec_ctx, pollset->polling_island, "ps");
1814
+ if (bag->pi != pi_new) {
1815
+ PI_ADD_REF(pi_new, poll_obj_string(bag_type));
1816
+ if (bag->pi != NULL) {
1817
+ PI_UNREF(exec_ctx, bag->pi, poll_obj_string(bag_type));
1633
1818
  }
1634
- pollset->polling_island = pi_new;
1819
+ bag->pi = pi_new;
1635
1820
  }
1636
1821
 
1637
- gpr_mu_unlock(&fd->mu);
1638
- gpr_mu_unlock(&pollset->mu);
1822
+ gpr_mu_unlock(&item->mu);
1823
+ gpr_mu_unlock(&bag->mu);
1824
+
1825
+ GRPC_LOG_IF_ERROR("add_poll_object", error);
1826
+ GPR_TIMER_END("add_poll_object", 0);
1827
+ }
1639
1828
 
1640
- GRPC_LOG_IF_ERROR("pollset_add_fd", error);
1829
+ static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1830
+ grpc_fd *fd) {
1831
+ add_poll_object(exec_ctx, &pollset->po, POLL_OBJ_POLLSET, &fd->po,
1832
+ POLL_OBJ_FD);
1641
1833
  }
1642
1834
 
1643
1835
  /*******************************************************************************
@@ -1645,142 +1837,60 @@ retry:
1645
1837
  */
1646
1838
 
1647
1839
  static grpc_pollset_set *pollset_set_create(void) {
1648
- grpc_pollset_set *pollset_set = gpr_malloc(sizeof(*pollset_set));
1649
- memset(pollset_set, 0, sizeof(*pollset_set));
1650
- gpr_mu_init(&pollset_set->mu);
1651
- return pollset_set;
1840
+ grpc_pollset_set *pss = gpr_malloc(sizeof(*pss));
1841
+ gpr_mu_init(&pss->po.mu);
1842
+ pss->po.pi = NULL;
1843
+ #ifdef PO_DEBUG
1844
+ pss->po.obj_type = POLL_OBJ_POLLSET_SET;
1845
+ #endif
1846
+ return pss;
1652
1847
  }
1653
1848
 
1654
- static void pollset_set_destroy(grpc_pollset_set *pollset_set) {
1655
- size_t i;
1656
- gpr_mu_destroy(&pollset_set->mu);
1657
- for (i = 0; i < pollset_set->fd_count; i++) {
1658
- GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set");
1849
+ static void pollset_set_destroy(grpc_pollset_set *pss) {
1850
+ gpr_mu_destroy(&pss->po.mu);
1851
+
1852
+ if (pss->po.pi != NULL) {
1853
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
1854
+ PI_UNREF(&exec_ctx, pss->po.pi, "pss_destroy");
1855
+ grpc_exec_ctx_finish(&exec_ctx);
1659
1856
  }
1660
- gpr_free(pollset_set->pollsets);
1661
- gpr_free(pollset_set->pollset_sets);
1662
- gpr_free(pollset_set->fds);
1663
- gpr_free(pollset_set);
1857
+
1858
+ gpr_free(pss);
1664
1859
  }
1665
1860
 
1666
- static void pollset_set_add_fd(grpc_exec_ctx *exec_ctx,
1667
- grpc_pollset_set *pollset_set, grpc_fd *fd) {
1668
- size_t i;
1669
- gpr_mu_lock(&pollset_set->mu);
1670
- if (pollset_set->fd_count == pollset_set->fd_capacity) {
1671
- pollset_set->fd_capacity = GPR_MAX(8, 2 * pollset_set->fd_capacity);
1672
- pollset_set->fds = gpr_realloc(
1673
- pollset_set->fds, pollset_set->fd_capacity * sizeof(*pollset_set->fds));
1674
- }
1675
- GRPC_FD_REF(fd, "pollset_set");
1676
- pollset_set->fds[pollset_set->fd_count++] = fd;
1677
- for (i = 0; i < pollset_set->pollset_count; i++) {
1678
- pollset_add_fd(exec_ctx, pollset_set->pollsets[i], fd);
1679
- }
1680
- for (i = 0; i < pollset_set->pollset_set_count; i++) {
1681
- pollset_set_add_fd(exec_ctx, pollset_set->pollset_sets[i], fd);
1682
- }
1683
- gpr_mu_unlock(&pollset_set->mu);
1861
+ static void pollset_set_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset_set *pss,
1862
+ grpc_fd *fd) {
1863
+ add_poll_object(exec_ctx, &pss->po, POLL_OBJ_POLLSET_SET, &fd->po,
1864
+ POLL_OBJ_FD);
1684
1865
  }
1685
1866
 
1686
- static void pollset_set_del_fd(grpc_exec_ctx *exec_ctx,
1687
- grpc_pollset_set *pollset_set, grpc_fd *fd) {
1688
- size_t i;
1689
- gpr_mu_lock(&pollset_set->mu);
1690
- for (i = 0; i < pollset_set->fd_count; i++) {
1691
- if (pollset_set->fds[i] == fd) {
1692
- pollset_set->fd_count--;
1693
- GPR_SWAP(grpc_fd *, pollset_set->fds[i],
1694
- pollset_set->fds[pollset_set->fd_count]);
1695
- GRPC_FD_UNREF(fd, "pollset_set");
1696
- break;
1697
- }
1698
- }
1699
- for (i = 0; i < pollset_set->pollset_set_count; i++) {
1700
- pollset_set_del_fd(exec_ctx, pollset_set->pollset_sets[i], fd);
1701
- }
1702
- gpr_mu_unlock(&pollset_set->mu);
1867
+ static void pollset_set_del_fd(grpc_exec_ctx *exec_ctx, grpc_pollset_set *pss,
1868
+ grpc_fd *fd) {
1869
+ /* Nothing to do */
1703
1870
  }
1704
1871
 
1705
1872
  static void pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
1706
- grpc_pollset_set *pollset_set,
1707
- grpc_pollset *pollset) {
1708
- size_t i, j;
1709
- gpr_mu_lock(&pollset_set->mu);
1710
- if (pollset_set->pollset_count == pollset_set->pollset_capacity) {
1711
- pollset_set->pollset_capacity =
1712
- GPR_MAX(8, 2 * pollset_set->pollset_capacity);
1713
- pollset_set->pollsets =
1714
- gpr_realloc(pollset_set->pollsets, pollset_set->pollset_capacity *
1715
- sizeof(*pollset_set->pollsets));
1716
- }
1717
- pollset_set->pollsets[pollset_set->pollset_count++] = pollset;
1718
- for (i = 0, j = 0; i < pollset_set->fd_count; i++) {
1719
- if (fd_is_orphaned(pollset_set->fds[i])) {
1720
- GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set");
1721
- } else {
1722
- pollset_add_fd(exec_ctx, pollset, pollset_set->fds[i]);
1723
- pollset_set->fds[j++] = pollset_set->fds[i];
1724
- }
1725
- }
1726
- pollset_set->fd_count = j;
1727
- gpr_mu_unlock(&pollset_set->mu);
1873
+ grpc_pollset_set *pss, grpc_pollset *ps) {
1874
+ add_poll_object(exec_ctx, &pss->po, POLL_OBJ_POLLSET_SET, &ps->po,
1875
+ POLL_OBJ_POLLSET);
1728
1876
  }
1729
1877
 
1730
1878
  static void pollset_set_del_pollset(grpc_exec_ctx *exec_ctx,
1731
- grpc_pollset_set *pollset_set,
1732
- grpc_pollset *pollset) {
1733
- size_t i;
1734
- gpr_mu_lock(&pollset_set->mu);
1735
- for (i = 0; i < pollset_set->pollset_count; i++) {
1736
- if (pollset_set->pollsets[i] == pollset) {
1737
- pollset_set->pollset_count--;
1738
- GPR_SWAP(grpc_pollset *, pollset_set->pollsets[i],
1739
- pollset_set->pollsets[pollset_set->pollset_count]);
1740
- break;
1741
- }
1742
- }
1743
- gpr_mu_unlock(&pollset_set->mu);
1879
+ grpc_pollset_set *pss, grpc_pollset *ps) {
1880
+ /* Nothing to do */
1744
1881
  }
1745
1882
 
1746
1883
  static void pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx,
1747
1884
  grpc_pollset_set *bag,
1748
1885
  grpc_pollset_set *item) {
1749
- size_t i, j;
1750
- gpr_mu_lock(&bag->mu);
1751
- if (bag->pollset_set_count == bag->pollset_set_capacity) {
1752
- bag->pollset_set_capacity = GPR_MAX(8, 2 * bag->pollset_set_capacity);
1753
- bag->pollset_sets =
1754
- gpr_realloc(bag->pollset_sets,
1755
- bag->pollset_set_capacity * sizeof(*bag->pollset_sets));
1756
- }
1757
- bag->pollset_sets[bag->pollset_set_count++] = item;
1758
- for (i = 0, j = 0; i < bag->fd_count; i++) {
1759
- if (fd_is_orphaned(bag->fds[i])) {
1760
- GRPC_FD_UNREF(bag->fds[i], "pollset_set");
1761
- } else {
1762
- pollset_set_add_fd(exec_ctx, item, bag->fds[i]);
1763
- bag->fds[j++] = bag->fds[i];
1764
- }
1765
- }
1766
- bag->fd_count = j;
1767
- gpr_mu_unlock(&bag->mu);
1886
+ add_poll_object(exec_ctx, &bag->po, POLL_OBJ_POLLSET_SET, &item->po,
1887
+ POLL_OBJ_POLLSET_SET);
1768
1888
  }
1769
1889
 
1770
1890
  static void pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx,
1771
1891
  grpc_pollset_set *bag,
1772
1892
  grpc_pollset_set *item) {
1773
- size_t i;
1774
- gpr_mu_lock(&bag->mu);
1775
- for (i = 0; i < bag->pollset_set_count; i++) {
1776
- if (bag->pollset_sets[i] == item) {
1777
- bag->pollset_set_count--;
1778
- GPR_SWAP(grpc_pollset_set *, bag->pollset_sets[i],
1779
- bag->pollset_sets[bag->pollset_set_count]);
1780
- break;
1781
- }
1782
- }
1783
- gpr_mu_unlock(&bag->mu);
1893
+ /* Nothing to do */
1784
1894
  }
1785
1895
 
1786
1896
  /* Test helper functions
@@ -1788,9 +1898,9 @@ static void pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx,
1788
1898
  void *grpc_fd_get_polling_island(grpc_fd *fd) {
1789
1899
  polling_island *pi;
1790
1900
 
1791
- gpr_mu_lock(&fd->mu);
1792
- pi = fd->polling_island;
1793
- gpr_mu_unlock(&fd->mu);
1901
+ gpr_mu_lock(&fd->po.mu);
1902
+ pi = fd->po.pi;
1903
+ gpr_mu_unlock(&fd->po.mu);
1794
1904
 
1795
1905
  return pi;
1796
1906
  }
@@ -1798,9 +1908,9 @@ void *grpc_fd_get_polling_island(grpc_fd *fd) {
1798
1908
  void *grpc_pollset_get_polling_island(grpc_pollset *ps) {
1799
1909
  polling_island *pi;
1800
1910
 
1801
- gpr_mu_lock(&ps->mu);
1802
- pi = ps->polling_island;
1803
- gpr_mu_unlock(&ps->mu);
1911
+ gpr_mu_lock(&ps->po.mu);
1912
+ pi = ps->po.pi;
1913
+ gpr_mu_unlock(&ps->po.mu);
1804
1914
 
1805
1915
  return pi;
1806
1916
  }
@@ -1859,6 +1969,10 @@ static const grpc_event_engine_vtable vtable = {
1859
1969
 
1860
1970
  .kick_poller = kick_poller,
1861
1971
 
1972
+ .workqueue_ref = workqueue_ref,
1973
+ .workqueue_unref = workqueue_unref,
1974
+ .workqueue_scheduler = workqueue_scheduler,
1975
+
1862
1976
  .shutdown_engine = shutdown_engine,
1863
1977
  };
1864
1978
 
@@ -1883,12 +1997,16 @@ const grpc_event_engine_vtable *grpc_init_epoll_linux(void) {
1883
1997
  return NULL;
1884
1998
  }
1885
1999
 
2000
+ if (!grpc_has_wakeup_fd()) {
2001
+ return NULL;
2002
+ }
2003
+
1886
2004
  if (!is_epoll_available()) {
1887
2005
  return NULL;
1888
2006
  }
1889
2007
 
1890
2008
  if (!is_grpc_wakeup_signal_initialized) {
1891
- grpc_use_signal(SIGRTMIN + 2);
2009
+ grpc_use_signal(SIGRTMIN + 6);
1892
2010
  }
1893
2011
 
1894
2012
  fd_global_init();
@@ -1905,13 +2023,13 @@ const grpc_event_engine_vtable *grpc_init_epoll_linux(void) {
1905
2023
  return &vtable;
1906
2024
  }
1907
2025
 
1908
- #else /* defined(GPR_LINUX_EPOLL) */
1909
- #if defined(GPR_POSIX_SOCKET)
2026
+ #else /* defined(GRPC_LINUX_EPOLL) */
2027
+ #if defined(GRPC_POSIX_SOCKET)
1910
2028
  #include "src/core/lib/iomgr/ev_posix.h"
1911
- /* If GPR_LINUX_EPOLL is not defined, it means epoll is not available. Return
2029
+ /* If GRPC_LINUX_EPOLL is not defined, it means epoll is not available. Return
1912
2030
  * NULL */
1913
2031
  const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { return NULL; }
1914
- #endif /* defined(GPR_POSIX_SOCKET) */
2032
+ #endif /* defined(GRPC_POSIX_SOCKET) */
1915
2033
 
1916
2034
  void grpc_use_signal(int signum) {}
1917
- #endif /* !defined(GPR_LINUX_EPOLL) */
2035
+ #endif /* !defined(GRPC_LINUX_EPOLL) */