grpc 0.14.1 → 0.15.0

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 (277) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1398 -817
  3. data/include/grpc/compression.h +2 -1
  4. data/include/grpc/grpc.h +10 -1
  5. data/include/grpc/grpc_cronet.h +51 -0
  6. data/include/grpc/grpc_posix.h +70 -0
  7. data/include/grpc/impl/codegen/atm.h +2 -2
  8. data/include/grpc/impl/codegen/{atm_win32.h → atm_windows.h} +3 -3
  9. data/include/grpc/impl/codegen/compression_types.h +39 -5
  10. data/include/grpc/impl/codegen/connectivity_state.h +1 -1
  11. data/include/grpc/impl/codegen/grpc_types.h +10 -0
  12. data/include/grpc/impl/codegen/log.h +2 -1
  13. data/include/grpc/impl/codegen/port_platform.h +30 -12
  14. data/include/grpc/impl/codegen/slice_buffer.h +2 -3
  15. data/include/grpc/impl/codegen/sync.h +2 -2
  16. data/include/grpc/impl/codegen/{sync_win32.h → sync_windows.h} +3 -3
  17. data/include/grpc/support/{sync_win32.h → atm_windows.h} +4 -4
  18. data/include/grpc/support/avl.h +5 -0
  19. data/include/grpc/support/{log_win32.h → log_windows.h} +3 -3
  20. data/include/grpc/support/string_util.h +2 -1
  21. data/include/grpc/support/{atm_win32.h → sync_windows.h} +4 -4
  22. data/src/core/ext/census/gen/census.pb.c +179 -0
  23. data/src/core/ext/census/gen/census.pb.h +294 -0
  24. data/src/core/ext/census/grpc_filter.c +11 -7
  25. data/src/core/ext/client_config/channel_connectivity.c +28 -14
  26. data/src/core/ext/client_config/client_channel.c +77 -53
  27. data/src/core/ext/client_config/connector.h +1 -1
  28. data/src/core/ext/client_config/lb_policy.c +9 -6
  29. data/src/core/ext/client_config/lb_policy.h +9 -5
  30. data/src/core/ext/client_config/subchannel.c +58 -39
  31. data/src/core/ext/client_config/subchannel.h +3 -2
  32. data/src/core/ext/client_config/subchannel_call_holder.c +34 -19
  33. data/src/core/ext/client_config/subchannel_call_holder.h +2 -1
  34. data/src/core/ext/client_config/subchannel_index.c +20 -9
  35. data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +7 -7
  36. data/src/core/ext/lb_policy/grpclb/load_balancer_api.h +5 -5
  37. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/{v0 → v1}/load_balancer.pb.c +29 -30
  38. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +178 -0
  39. data/src/core/ext/lb_policy/pick_first/pick_first.c +65 -45
  40. data/src/core/ext/lb_policy/round_robin/round_robin.c +84 -43
  41. data/src/core/ext/load_reporting/load_reporting.c +133 -0
  42. data/src/core/ext/load_reporting/load_reporting.h +75 -0
  43. data/src/core/ext/load_reporting/load_reporting_filter.c +151 -0
  44. data/src/core/ext/load_reporting/load_reporting_filter.h +41 -0
  45. data/src/core/ext/resolver/dns/native/dns_resolver.c +22 -8
  46. data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +2 -2
  47. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +4 -4
  48. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +95 -0
  49. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +14 -18
  50. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +49 -24
  51. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +82 -0
  52. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +104 -60
  53. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +232 -0
  54. data/src/{ruby/ext/grpc/rb_signal.c → core/ext/transport/chttp2/transport/bin_decoder.h} +27 -31
  55. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +481 -260
  56. data/src/core/ext/transport/chttp2/transport/frame.h +1 -7
  57. data/src/core/ext/transport/chttp2/transport/frame_data.c +44 -27
  58. data/src/core/ext/transport/chttp2/transport/frame_data.h +6 -5
  59. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +23 -17
  60. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +2 -2
  61. data/src/core/ext/transport/chttp2/transport/frame_ping.c +12 -7
  62. data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -3
  63. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +25 -12
  64. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +2 -2
  65. data/src/core/ext/transport/chttp2/transport/frame_settings.c +23 -21
  66. data/src/core/ext/transport/chttp2/transport/frame_settings.h +2 -2
  67. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +17 -9
  68. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +2 -2
  69. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +365 -287
  70. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -6
  71. data/src/core/ext/transport/chttp2/transport/hpack_table.c +24 -20
  72. data/src/core/ext/transport/chttp2/transport/hpack_table.h +5 -4
  73. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +1 -0
  74. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +1 -0
  75. data/src/core/ext/transport/chttp2/transport/internal.h +34 -32
  76. data/src/core/ext/transport/chttp2/transport/parsing.c +296 -212
  77. data/src/core/ext/transport/chttp2/transport/writing.c +12 -9
  78. data/src/core/lib/channel/channel_args.c +26 -12
  79. data/src/core/lib/channel/channel_args.h +1 -1
  80. data/src/core/lib/channel/channel_stack.c +12 -8
  81. data/src/core/lib/channel/channel_stack.h +27 -11
  82. data/src/core/lib/channel/channel_stack_builder.c +2 -2
  83. data/src/core/lib/channel/compress_filter.c +26 -31
  84. data/src/core/lib/channel/compress_filter.h +4 -4
  85. data/src/core/lib/channel/connected_channel.c +7 -5
  86. data/src/core/lib/channel/http_client_filter.c +34 -8
  87. data/src/core/lib/channel/http_client_filter.h +1 -1
  88. data/src/core/lib/channel/http_server_filter.c +21 -12
  89. data/src/core/lib/compression/{compression_algorithm.c → compression.c} +22 -21
  90. data/src/core/lib/http/httpcli.c +81 -59
  91. data/src/core/lib/http/httpcli.h +11 -15
  92. data/src/core/lib/http/httpcli_security_connector.c +5 -3
  93. data/src/core/lib/http/parser.c +127 -118
  94. data/src/core/lib/http/parser.h +11 -6
  95. data/src/core/lib/iomgr/closure.c +20 -16
  96. data/src/core/lib/iomgr/closure.h +19 -15
  97. data/src/core/lib/iomgr/endpoint.h +1 -1
  98. data/src/core/lib/iomgr/endpoint_pair_posix.c +2 -2
  99. data/src/core/lib/iomgr/error.c +535 -0
  100. data/src/core/lib/iomgr/error.h +192 -0
  101. data/src/core/lib/iomgr/ev_poll_and_epoll_posix.c +190 -83
  102. data/src/core/lib/iomgr/ev_poll_posix.c +1267 -0
  103. data/src/{ruby/ext/grpc/rb_signal.h → core/lib/iomgr/ev_poll_posix.h} +7 -5
  104. data/src/core/lib/iomgr/ev_posix.c +104 -14
  105. data/src/core/lib/iomgr/ev_posix.h +17 -7
  106. data/src/core/lib/iomgr/exec_ctx.c +25 -7
  107. data/src/core/lib/iomgr/exec_ctx.h +27 -8
  108. data/src/core/lib/iomgr/executor.c +2 -2
  109. data/src/core/lib/iomgr/executor.h +1 -1
  110. data/src/core/lib/iomgr/iocp_windows.c +2 -41
  111. data/src/core/lib/iomgr/iocp_windows.h +0 -8
  112. data/src/core/lib/iomgr/iomgr.c +5 -4
  113. data/src/core/lib/iomgr/iomgr_posix.c +5 -1
  114. data/src/core/lib/iomgr/iomgr_windows.c +1 -1
  115. data/src/core/lib/{support → iomgr}/load_file.c +15 -17
  116. data/src/core/lib/{support → iomgr}/load_file.h +8 -7
  117. data/src/core/lib/iomgr/polling_entity.c +104 -0
  118. data/src/core/lib/iomgr/polling_entity.h +81 -0
  119. data/src/core/lib/iomgr/pollset.h +6 -5
  120. data/src/core/lib/iomgr/pollset_set_windows.c +4 -1
  121. data/src/core/lib/iomgr/pollset_windows.c +10 -6
  122. data/src/core/lib/iomgr/resolve_address.h +5 -9
  123. data/src/core/lib/iomgr/resolve_address_posix.c +55 -38
  124. data/src/core/lib/iomgr/resolve_address_windows.c +51 -37
  125. data/src/core/lib/iomgr/sockaddr.h +2 -2
  126. data/src/core/lib/iomgr/{sockaddr_win32.h → sockaddr_windows.h} +3 -3
  127. data/src/core/lib/iomgr/socket_utils_common_posix.c +92 -45
  128. data/src/core/lib/iomgr/socket_utils_posix.h +19 -12
  129. data/src/core/lib/iomgr/socket_windows.c +61 -2
  130. data/src/core/lib/iomgr/socket_windows.h +13 -0
  131. data/src/core/lib/iomgr/tcp_client_posix.c +54 -39
  132. data/src/core/lib/iomgr/tcp_client_windows.c +34 -34
  133. data/src/core/lib/iomgr/tcp_posix.c +43 -39
  134. data/src/core/lib/iomgr/tcp_server.h +5 -3
  135. data/src/core/lib/iomgr/tcp_server_posix.c +103 -64
  136. data/src/core/lib/iomgr/tcp_server_windows.c +114 -101
  137. data/src/core/lib/iomgr/tcp_windows.c +45 -50
  138. data/src/core/lib/iomgr/tcp_windows.h +1 -1
  139. data/src/core/lib/iomgr/timer.c +26 -13
  140. data/src/core/lib/iomgr/udp_server.c +28 -4
  141. data/src/core/lib/iomgr/udp_server.h +5 -1
  142. data/src/core/lib/iomgr/unix_sockets_posix.c +8 -7
  143. data/src/core/lib/iomgr/unix_sockets_posix.h +2 -1
  144. data/src/core/lib/iomgr/unix_sockets_posix_noop.c +4 -2
  145. data/src/core/lib/iomgr/wakeup_fd_eventfd.c +15 -5
  146. data/src/core/lib/iomgr/wakeup_fd_pipe.c +13 -9
  147. data/src/core/lib/iomgr/wakeup_fd_posix.c +6 -6
  148. data/src/core/lib/iomgr/wakeup_fd_posix.h +9 -6
  149. data/src/core/lib/iomgr/workqueue.h +5 -4
  150. data/src/core/lib/iomgr/workqueue_posix.c +40 -26
  151. data/src/core/lib/iomgr/workqueue_windows.c +2 -2
  152. data/src/core/lib/profiling/basic_timers.c +2 -2
  153. data/src/core/lib/security/{security_context.c → context/security_context.c} +1 -1
  154. data/src/core/lib/security/{security_context.h → context/security_context.h} +4 -4
  155. data/src/core/lib/security/credentials/composite/composite_credentials.c +263 -0
  156. data/src/core/lib/security/credentials/composite/composite_credentials.h +72 -0
  157. data/src/core/lib/security/credentials/credentials.c +233 -0
  158. data/src/core/lib/security/{credentials.h → credentials/credentials.h} +19 -157
  159. data/src/core/lib/security/{credentials_metadata.c → credentials/credentials_metadata.c} +1 -1
  160. data/src/core/lib/security/credentials/fake/fake_credentials.c +139 -0
  161. data/src/core/lib/security/credentials/fake/fake_credentials.h +56 -0
  162. data/src/core/lib/security/{credentials_posix.c → credentials/google_default/credentials_posix.c} +1 -1
  163. data/src/core/lib/security/{credentials_win32.c → credentials/google_default/credentials_windows.c} +3 -3
  164. data/src/core/lib/security/{google_default_credentials.c → credentials/google_default/google_default_credentials.c} +93 -35
  165. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +46 -0
  166. data/src/core/lib/security/credentials/iam/iam_credentials.c +85 -0
  167. data/src/core/lib/security/credentials/iam/iam_credentials.h +44 -0
  168. data/src/core/lib/security/{json_token.c → credentials/jwt/json_token.c} +10 -101
  169. data/src/core/lib/security/{json_token.h → credentials/jwt/json_token.h} +3 -33
  170. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +160 -0
  171. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +62 -0
  172. data/src/core/lib/security/{jwt_verifier.c → credentials/jwt/jwt_verifier.c} +35 -15
  173. data/src/core/lib/security/{jwt_verifier.h → credentials/jwt/jwt_verifier.h} +3 -3
  174. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +433 -0
  175. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +109 -0
  176. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +129 -0
  177. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +45 -0
  178. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +240 -0
  179. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +48 -0
  180. data/src/core/lib/security/{auth_filters.h → transport/auth_filters.h} +3 -3
  181. data/src/core/lib/security/{client_auth_filter.c → transport/client_auth_filter.c} +27 -20
  182. data/src/core/lib/security/{handshake.c → transport/handshake.c} +77 -45
  183. data/src/core/lib/security/{handshake.h → transport/handshake.h} +9 -11
  184. data/src/core/lib/security/{secure_endpoint.c → transport/secure_endpoint.c} +19 -12
  185. data/src/core/lib/security/{secure_endpoint.h → transport/secure_endpoint.h} +3 -3
  186. data/src/core/lib/security/{security_connector.c → transport/security_connector.c} +26 -17
  187. data/src/core/lib/security/{security_connector.h → transport/security_connector.h} +8 -8
  188. data/src/core/lib/security/{server_auth_filter.c → transport/server_auth_filter.c} +24 -16
  189. data/src/core/lib/security/transport/tsi_error.c +40 -0
  190. data/src/core/lib/security/transport/tsi_error.h +42 -0
  191. data/src/core/lib/security/{b64.c → util/b64.c} +1 -1
  192. data/src/core/lib/security/{b64.h → util/b64.h} +3 -3
  193. data/src/core/lib/security/util/json_util.c +61 -0
  194. data/src/core/lib/security/util/json_util.h +55 -0
  195. data/src/core/lib/support/avl.c +11 -0
  196. data/src/core/lib/support/cpu_windows.c +2 -2
  197. data/src/core/lib/support/{env_win32.c → env_windows.c} +3 -3
  198. data/src/core/lib/support/log.c +3 -1
  199. data/src/core/lib/support/log_linux.c +2 -2
  200. data/src/core/lib/support/{log_win32.c → log_windows.c} +4 -4
  201. data/src/core/lib/support/murmur_hash.c +3 -5
  202. data/src/core/lib/support/string.c +10 -0
  203. data/src/core/lib/support/string.h +4 -0
  204. data/src/core/lib/support/{string_util_win32.c → string_util_windows.c} +3 -3
  205. data/src/core/lib/support/{string_win32.c → string_windows.c} +2 -2
  206. data/src/core/lib/support/{string_win32.h → string_windows.h} +5 -5
  207. data/src/core/lib/support/subprocess_windows.c +1 -1
  208. data/src/core/lib/support/{sync_win32.c → sync_windows.c} +2 -2
  209. data/src/core/lib/support/{thd_win32.c → thd_windows.c} +2 -2
  210. data/src/core/lib/support/{time_win32.c → time_windows.c} +2 -2
  211. data/src/core/lib/support/tmpfile_msys.c +1 -1
  212. data/src/core/lib/support/{tmpfile_win32.c → tmpfile_windows.c} +3 -3
  213. data/src/core/lib/surface/alarm.c +2 -2
  214. data/src/core/lib/surface/byte_buffer_reader.c +13 -6
  215. data/src/core/lib/surface/call.c +323 -123
  216. data/src/core/lib/surface/call.h +2 -0
  217. data/src/core/lib/surface/call_log_batch.c +1 -1
  218. data/src/core/lib/surface/channel.c +64 -15
  219. data/src/core/lib/surface/channel.h +9 -0
  220. data/src/core/lib/surface/channel_ping.c +3 -3
  221. data/src/core/lib/surface/completion_queue.c +75 -19
  222. data/src/core/lib/surface/completion_queue.h +7 -2
  223. data/src/core/lib/surface/init.c +2 -1
  224. data/src/core/lib/surface/init_secure.c +4 -4
  225. data/src/core/lib/surface/lame_client.c +12 -8
  226. data/src/core/lib/surface/server.c +213 -120
  227. data/src/core/lib/surface/server.h +1 -0
  228. data/src/core/lib/surface/version.c +1 -1
  229. data/src/core/lib/transport/connectivity_state.c +40 -18
  230. data/src/core/lib/transport/connectivity_state.h +4 -1
  231. data/src/core/lib/transport/metadata.c +23 -23
  232. data/src/core/lib/transport/metadata.h +4 -0
  233. data/src/core/lib/transport/metadata_batch.c +9 -0
  234. data/src/core/lib/transport/metadata_batch.h +3 -0
  235. data/src/core/lib/transport/static_metadata.c +6 -5
  236. data/src/core/lib/transport/static_metadata.h +64 -60
  237. data/src/core/lib/transport/transport.c +24 -12
  238. data/src/core/lib/transport/transport.h +6 -5
  239. data/src/core/lib/transport/transport_impl.h +4 -0
  240. data/src/core/lib/transport/transport_op_string.c +2 -2
  241. data/src/core/plugin_registry/grpc_plugin_registry.c +4 -0
  242. data/src/ruby/bin/math_services.rb +41 -2
  243. data/src/ruby/ext/grpc/rb_call.c +42 -40
  244. data/src/ruby/ext/grpc/rb_channel.c +1 -1
  245. data/src/ruby/ext/grpc/rb_completion_queue.c +59 -6
  246. data/src/ruby/ext/grpc/rb_completion_queue.h +1 -1
  247. data/src/ruby/ext/grpc/rb_grpc.c +1 -3
  248. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +12 -2
  249. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +21 -5
  250. data/src/ruby/ext/grpc/rb_loader.c +1 -1
  251. data/src/ruby/ext/grpc/rb_server.c +5 -3
  252. data/src/ruby/lib/grpc.rb +0 -3
  253. data/src/ruby/lib/grpc/errors.rb +3 -2
  254. data/src/ruby/lib/grpc/generic/active_call.rb +32 -42
  255. data/src/ruby/lib/grpc/generic/bidi_call.rb +20 -0
  256. data/src/ruby/lib/grpc/generic/client_stub.rb +31 -54
  257. data/src/ruby/lib/grpc/generic/rpc_desc.rb +4 -4
  258. data/src/ruby/lib/grpc/generic/rpc_server.rb +12 -23
  259. data/src/ruby/lib/grpc/generic/service.rb +8 -8
  260. data/src/ruby/lib/grpc/version.rb +1 -1
  261. data/src/ruby/pb/grpc/health/v1/health_services.rb +30 -2
  262. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb +34 -4
  263. data/src/ruby/pb/grpc/testing/metrics_services.rb +39 -2
  264. data/src/ruby/pb/src/proto/grpc/testing/empty.rb +15 -0
  265. data/src/ruby/pb/src/proto/grpc/testing/messages.rb +84 -0
  266. data/src/ruby/pb/src/proto/grpc/testing/test.rb +14 -0
  267. data/src/ruby/pb/src/proto/grpc/testing/test_services.rb +110 -0
  268. data/src/ruby/pb/test/client.rb +5 -2
  269. data/src/ruby/spec/generic/active_call_spec.rb +3 -2
  270. data/src/ruby/spec/generic/client_stub_spec.rb +27 -24
  271. data/src/ruby/spec/generic/rpc_desc_spec.rb +11 -11
  272. data/src/ruby/spec/generic/rpc_server_spec.rb +42 -61
  273. data/src/ruby/spec/pb/health/checker_spec.rb +3 -5
  274. metadata +86 -48
  275. data/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h +0 -182
  276. data/src/core/lib/security/credentials.c +0 -1296
  277. data/src/ruby/lib/grpc/signals.rb +0 -69
@@ -0,0 +1,192 @@
1
+ /*
2
+ *
3
+ * Copyright 2016, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #ifndef GRPC_CORE_LIB_IOMGR_ERROR_H
35
+ #define GRPC_CORE_LIB_IOMGR_ERROR_H
36
+
37
+ #include <stdbool.h>
38
+ #include <stdint.h>
39
+
40
+ #include <grpc/support/time.h>
41
+
42
+ /// Opaque representation of an error.
43
+ /// Errors are refcounted objects that represent the result of an operation.
44
+ /// Ownership laws:
45
+ /// if a grpc_error is returned by a function, the caller owns a ref to that
46
+ /// instance
47
+ /// if a grpc_error is passed to a grpc_closure callback function (functions
48
+ /// with the signature:
49
+ /// void (*f)(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error))
50
+ /// then those functions do not automatically own a ref to error
51
+ /// if a grpc_error is passed to *ANY OTHER FUNCTION* then that function takes
52
+ /// ownership of the error
53
+ /// Errors have:
54
+ /// a set of ints, strings, and timestamps that describe the error
55
+ /// always present are:
56
+ /// GRPC_ERROR_STR_FILE, GRPC_ERROR_INT_FILE_LINE - source location the error
57
+ /// was generated
58
+ /// GRPC_ERROR_STR_DESCRIPTION - a human readable description of the error
59
+ /// GRPC_ERROR_TIME_CREATED - a timestamp indicating when the error happened
60
+ /// an error can also have children; these are other errors that are believed
61
+ /// to have contributed to this one. By accumulating children, we can begin
62
+ /// to root cause high level failures from low level failures, without having
63
+ /// to derive execution paths from log lines
64
+ typedef struct grpc_error grpc_error;
65
+
66
+ typedef enum {
67
+ /// 'errno' from the operating system
68
+ GRPC_ERROR_INT_ERRNO,
69
+ /// __LINE__ from the call site creating the error
70
+ GRPC_ERROR_INT_FILE_LINE,
71
+ /// stream identifier: for errors that are associated with an individual
72
+ /// wire stream
73
+ GRPC_ERROR_INT_STREAM_ID,
74
+ /// grpc status code representing this error
75
+ GRPC_ERROR_INT_GRPC_STATUS,
76
+ /// offset into some binary blob (usually represented by
77
+ /// GRPC_ERROR_STR_RAW_BYTES) where the error occurred
78
+ GRPC_ERROR_INT_OFFSET,
79
+ /// context sensitive index associated with the error
80
+ GRPC_ERROR_INT_INDEX,
81
+ /// context sensitive size associated with the error
82
+ GRPC_ERROR_INT_SIZE,
83
+ /// http2 error code associated with the error (see the HTTP2 RFC)
84
+ GRPC_ERROR_INT_HTTP2_ERROR,
85
+ /// TSI status code associated with the error
86
+ GRPC_ERROR_INT_TSI_CODE,
87
+ /// grpc_security_status associated with the error
88
+ GRPC_ERROR_INT_SECURITY_STATUS,
89
+ /// WSAGetLastError() reported when this error occurred
90
+ GRPC_ERROR_INT_WSA_ERROR,
91
+ /// File descriptor associated with this error
92
+ GRPC_ERROR_INT_FD,
93
+ /// HTTP status (i.e. 404)
94
+ GRPC_ERROR_INT_HTTP_STATUS,
95
+ } grpc_error_ints;
96
+
97
+ typedef enum {
98
+ /// top-level textual description of this error
99
+ GRPC_ERROR_STR_DESCRIPTION,
100
+ /// source file in which this error occurred
101
+ GRPC_ERROR_STR_FILE,
102
+ /// operating system description of this error
103
+ GRPC_ERROR_STR_OS_ERROR,
104
+ /// syscall that generated this error
105
+ GRPC_ERROR_STR_SYSCALL,
106
+ /// peer that we were trying to communicate when this error occurred
107
+ GRPC_ERROR_STR_TARGET_ADDRESS,
108
+ /// grpc status message associated with this error
109
+ GRPC_ERROR_STR_GRPC_MESSAGE,
110
+ /// hex dump (or similar) with the data that generated this error
111
+ GRPC_ERROR_STR_RAW_BYTES,
112
+ /// tsi error string associated with this error
113
+ GRPC_ERROR_STR_TSI_ERROR,
114
+ /// filename that we were trying to read/write when this error occurred
115
+ GRPC_ERROR_STR_FILENAME,
116
+ } grpc_error_strs;
117
+
118
+ typedef enum {
119
+ /// timestamp of error creation
120
+ GRPC_ERROR_TIME_CREATED,
121
+ } grpc_error_times;
122
+
123
+ #define GRPC_ERROR_NONE ((grpc_error *)NULL)
124
+ #define GRPC_ERROR_OOM ((grpc_error *)1)
125
+ #define GRPC_ERROR_CANCELLED ((grpc_error *)2)
126
+
127
+ const char *grpc_error_string(grpc_error *error);
128
+ void grpc_error_free_string(const char *str);
129
+
130
+ /// Create an error - but use GRPC_ERROR_CREATE instead
131
+ grpc_error *grpc_error_create(const char *file, int line, const char *desc,
132
+ grpc_error **referencing, size_t num_referencing);
133
+ /// Create an error (this is the preferred way of generating an error that is
134
+ /// not due to a system call - for system calls, use GRPC_OS_ERROR or
135
+ /// GRPC_WSA_ERROR as appropriate)
136
+ /// \a referencing is an array of num_referencing elements indicating one or
137
+ /// more errors that are believed to have contributed to this one
138
+ /// err = grpc_error_create(x, y, z, r, nr) is equivalent to:
139
+ /// err = grpc_error_create(x, y, z, NULL, 0);
140
+ /// for (i=0; i<nr; i++) err = grpc_error_add_child(err, r[i]);
141
+ #define GRPC_ERROR_CREATE(desc) \
142
+ grpc_error_create(__FILE__, __LINE__, desc, NULL, 0)
143
+
144
+ // Create an error that references some other errors. This function adds a
145
+ // reference to each error in errs - it does not consume an existing reference
146
+ #define GRPC_ERROR_CREATE_REFERENCING(desc, errs, count) \
147
+ grpc_error_create(__FILE__, __LINE__, desc, errs, count)
148
+
149
+ //#define GRPC_ERROR_REFCOUNT_DEBUG
150
+ #ifdef GRPC_ERROR_REFCOUNT_DEBUG
151
+ grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line,
152
+ const char *func);
153
+ void grpc_error_unref(grpc_error *err, const char *file, int line,
154
+ const char *func);
155
+ #define GRPC_ERROR_REF(err) grpc_error_ref(err, __FILE__, __LINE__, __func__)
156
+ #define GRPC_ERROR_UNREF(err) \
157
+ grpc_error_unref(err, __FILE__, __LINE__, __func__)
158
+ #else
159
+ grpc_error *grpc_error_ref(grpc_error *err);
160
+ void grpc_error_unref(grpc_error *err);
161
+ #define GRPC_ERROR_REF(err) grpc_error_ref(err)
162
+ #define GRPC_ERROR_UNREF(err) grpc_error_unref(err)
163
+ #endif
164
+
165
+ grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which,
166
+ intptr_t value);
167
+ bool grpc_error_get_int(grpc_error *error, grpc_error_ints which, intptr_t *p);
168
+ grpc_error *grpc_error_set_time(grpc_error *src, grpc_error_times which,
169
+ gpr_timespec value);
170
+ grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
171
+ const char *value);
172
+ /// Add a child error: an error that is believed to have contributed to this
173
+ /// error occurring. Allows root causing high level errors from lower level
174
+ /// errors that contributed to them.
175
+ grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child);
176
+ grpc_error *grpc_os_error(const char *file, int line, int err,
177
+ const char *call_name);
178
+ /// create an error associated with errno!=0 (an 'operating system' error)
179
+ #define GRPC_OS_ERROR(err, call_name) \
180
+ grpc_os_error(__FILE__, __LINE__, err, call_name)
181
+ grpc_error *grpc_wsa_error(const char *file, int line, int err,
182
+ const char *call_name);
183
+ /// windows only: create an error associated with WSAGetLastError()!=0
184
+ #define GRPC_WSA_ERROR(err, call_name) \
185
+ grpc_wsa_error(__FILE__, __LINE__, err, call_name)
186
+
187
+ bool grpc_log_if_error(const char *what, grpc_error *error, const char *file,
188
+ int line);
189
+ #define GRPC_LOG_IF_ERROR(what, error) \
190
+ grpc_log_if_error((what), (error), __FILE__, __LINE__)
191
+
192
+ #endif /* GRPC_CORE_LIB_IOMGR_ERROR_H */
@@ -126,6 +126,9 @@ struct grpc_fd {
126
126
  grpc_closure *on_done_closure;
127
127
 
128
128
  grpc_iomgr_object iomgr_object;
129
+
130
+ /* The pollset that last noticed and notified that the fd is readable */
131
+ grpc_pollset *read_notifier_pollset;
129
132
  };
130
133
 
131
134
  /* Begin polling on an fd.
@@ -147,7 +150,8 @@ static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
147
150
  if got_read or got_write are 1, also does the become_{readable,writable} as
148
151
  appropriate. */
149
152
  static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec,
150
- int got_read, int got_write);
153
+ int got_read, int got_write,
154
+ grpc_pollset *read_notifier_pollset);
151
155
 
152
156
  /* Return 1 if this fd is orphaned, 0 otherwise */
153
157
  static bool fd_is_orphaned(grpc_fd *fd);
@@ -217,9 +221,10 @@ struct grpc_pollset {
217
221
  struct grpc_pollset_vtable {
218
222
  void (*add_fd)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
219
223
  struct grpc_fd *fd, int and_unlock_pollset);
220
- void (*maybe_work_and_unlock)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
221
- grpc_pollset_worker *worker,
222
- gpr_timespec deadline, gpr_timespec now);
224
+ grpc_error *(*maybe_work_and_unlock)(grpc_exec_ctx *exec_ctx,
225
+ grpc_pollset *pollset,
226
+ grpc_pollset_worker *worker,
227
+ gpr_timespec deadline, gpr_timespec now);
223
228
  void (*finish_shutdown)(grpc_pollset *pollset);
224
229
  void (*destroy)(grpc_pollset *pollset);
225
230
  };
@@ -247,9 +252,9 @@ static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
247
252
  #define GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP 2
248
253
  /* As per pollset_kick, with an extended set of flags (defined above)
249
254
  -- mostly for fd_posix's use. */
250
- static void pollset_kick_ext(grpc_pollset *p,
251
- grpc_pollset_worker *specific_worker,
252
- uint32_t flags);
255
+ static grpc_error *pollset_kick_ext(grpc_pollset *p,
256
+ grpc_pollset_worker *specific_worker,
257
+ uint32_t flags) GRPC_MUST_USE_RESULT;
253
258
 
254
259
  /* turn a pollset into a multipoller: platform specific */
255
260
  typedef void (*platform_become_multipoller_type)(grpc_exec_ctx *exec_ctx,
@@ -342,6 +347,7 @@ static grpc_fd *alloc_fd(int fd) {
342
347
  r->on_done_closure = NULL;
343
348
  r->closed = 0;
344
349
  r->released = 0;
350
+ r->read_notifier_pollset = NULL;
345
351
  gpr_mu_unlock(&r->mu);
346
352
  return r;
347
353
  }
@@ -415,12 +421,13 @@ static bool fd_is_orphaned(grpc_fd *fd) {
415
421
  return (gpr_atm_acq_load(&fd->refst) & 1) == 0;
416
422
  }
417
423
 
418
- static void pollset_kick_locked(grpc_fd_watcher *watcher) {
424
+ static grpc_error *pollset_kick_locked(grpc_fd_watcher *watcher) {
419
425
  gpr_mu_lock(&watcher->pollset->mu);
420
426
  GPR_ASSERT(watcher->worker);
421
- pollset_kick_ext(watcher->pollset, watcher->worker,
422
- GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP);
427
+ grpc_error *err = pollset_kick_ext(watcher->pollset, watcher->worker,
428
+ GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP);
423
429
  gpr_mu_unlock(&watcher->pollset->mu);
430
+ return err;
424
431
  }
425
432
 
426
433
  static void maybe_wake_one_watcher_locked(grpc_fd *fd) {
@@ -459,7 +466,7 @@ static void close_fd_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
459
466
  } else {
460
467
  remove_fd_from_all_epoll_sets(fd->fd);
461
468
  }
462
- grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, true, NULL);
469
+ grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_NONE, NULL);
463
470
  }
464
471
 
465
472
  static int fd_wrapped_fd(grpc_fd *fd) {
@@ -508,15 +515,27 @@ static void fd_ref(grpc_fd *fd) { ref_by(fd, 2); }
508
515
  static void fd_unref(grpc_fd *fd) { unref_by(fd, 2); }
509
516
  #endif
510
517
 
518
+ static grpc_error *fd_shutdown_error(bool shutdown) {
519
+ if (!shutdown) {
520
+ return GRPC_ERROR_NONE;
521
+ } else {
522
+ return GRPC_ERROR_CREATE("FD shutdown");
523
+ }
524
+ }
525
+
511
526
  static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
512
527
  grpc_closure **st, grpc_closure *closure) {
513
- if (*st == CLOSURE_NOT_READY) {
528
+ if (fd->shutdown) {
529
+ grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"),
530
+ NULL);
531
+ } else if (*st == CLOSURE_NOT_READY) {
514
532
  /* not ready ==> switch to a waiting state by setting the closure */
515
533
  *st = closure;
516
534
  } else if (*st == CLOSURE_READY) {
517
535
  /* already ready ==> queue the closure to run immediately */
518
536
  *st = CLOSURE_NOT_READY;
519
- grpc_exec_ctx_enqueue(exec_ctx, closure, !fd->shutdown, NULL);
537
+ grpc_exec_ctx_sched(exec_ctx, closure, fd_shutdown_error(fd->shutdown),
538
+ NULL);
520
539
  maybe_wake_one_watcher_locked(fd);
521
540
  } else {
522
541
  /* upcallptr was set to a different closure. This is an error! */
@@ -539,19 +558,35 @@ static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
539
558
  return 0;
540
559
  } else {
541
560
  /* waiting ==> queue closure */
542
- grpc_exec_ctx_enqueue(exec_ctx, *st, !fd->shutdown, NULL);
561
+ grpc_exec_ctx_sched(exec_ctx, *st, fd_shutdown_error(fd->shutdown), NULL);
543
562
  *st = CLOSURE_NOT_READY;
544
563
  return 1;
545
564
  }
546
565
  }
547
566
 
567
+ static void set_read_notifier_pollset_locked(
568
+ grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_pollset *read_notifier_pollset) {
569
+ fd->read_notifier_pollset = read_notifier_pollset;
570
+ }
571
+
548
572
  static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
549
573
  gpr_mu_lock(&fd->mu);
550
- GPR_ASSERT(!fd->shutdown);
551
- fd->shutdown = 1;
552
- set_ready_locked(exec_ctx, fd, &fd->read_closure);
553
- set_ready_locked(exec_ctx, fd, &fd->write_closure);
574
+ /* only shutdown once */
575
+ if (!fd->shutdown) {
576
+ fd->shutdown = 1;
577
+ /* signal read/write closed to OS so that future operations fail */
578
+ shutdown(fd->fd, SHUT_RDWR);
579
+ set_ready_locked(exec_ctx, fd, &fd->read_closure);
580
+ set_ready_locked(exec_ctx, fd, &fd->write_closure);
581
+ }
582
+ gpr_mu_unlock(&fd->mu);
583
+ }
584
+
585
+ static bool fd_is_shutdown(grpc_fd *fd) {
586
+ gpr_mu_lock(&fd->mu);
587
+ bool r = fd->shutdown;
554
588
  gpr_mu_unlock(&fd->mu);
589
+ return r;
555
590
  }
556
591
 
557
592
  static void fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
@@ -568,6 +603,18 @@ static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
568
603
  gpr_mu_unlock(&fd->mu);
569
604
  }
570
605
 
606
+ /* Return the read-notifier pollset */
607
+ static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
608
+ grpc_fd *fd) {
609
+ grpc_pollset *notifier = NULL;
610
+
611
+ gpr_mu_lock(&fd->mu);
612
+ notifier = fd->read_notifier_pollset;
613
+ gpr_mu_unlock(&fd->mu);
614
+
615
+ return notifier;
616
+ }
617
+
571
618
  static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
572
619
  grpc_pollset_worker *worker, uint32_t read_mask,
573
620
  uint32_t write_mask, grpc_fd_watcher *watcher) {
@@ -620,7 +667,8 @@ static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
620
667
  }
621
668
 
622
669
  static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
623
- int got_read, int got_write) {
670
+ int got_read, int got_write,
671
+ grpc_pollset *read_notifier_pollset) {
624
672
  int was_polling = 0;
625
673
  int kick = 0;
626
674
  grpc_fd *fd = watcher->fd;
@@ -656,6 +704,10 @@ static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
656
704
  if (set_ready_locked(exec_ctx, fd, &fd->read_closure)) {
657
705
  kick = 1;
658
706
  }
707
+
708
+ if (read_notifier_pollset != NULL) {
709
+ set_read_notifier_pollset_locked(exec_ctx, fd, read_notifier_pollset);
710
+ }
659
711
  }
660
712
  if (got_write) {
661
713
  if (set_ready_locked(exec_ctx, fd, &fd->write_closure)) {
@@ -717,10 +769,19 @@ static void push_front_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
717
769
  worker->prev->next = worker->next->prev = worker;
718
770
  }
719
771
 
720
- static void pollset_kick_ext(grpc_pollset *p,
721
- grpc_pollset_worker *specific_worker,
722
- uint32_t flags) {
772
+ static void kick_append_error(grpc_error **composite, grpc_error *error) {
773
+ if (error == GRPC_ERROR_NONE) return;
774
+ if (*composite == GRPC_ERROR_NONE) {
775
+ *composite = GRPC_ERROR_CREATE("Kick Failure");
776
+ }
777
+ *composite = grpc_error_add_child(*composite, error);
778
+ }
779
+
780
+ static grpc_error *pollset_kick_ext(grpc_pollset *p,
781
+ grpc_pollset_worker *specific_worker,
782
+ uint32_t flags) {
723
783
  GPR_TIMER_BEGIN("pollset_kick_ext", 0);
784
+ grpc_error *error = GRPC_ERROR_NONE;
724
785
 
725
786
  /* pollset->mu already held */
726
787
  if (specific_worker != NULL) {
@@ -730,25 +791,28 @@ static void pollset_kick_ext(grpc_pollset *p,
730
791
  for (specific_worker = p->root_worker.next;
731
792
  specific_worker != &p->root_worker;
732
793
  specific_worker = specific_worker->next) {
733
- grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
794
+ kick_append_error(
795
+ &error, grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd));
734
796
  }
735
- p->kicked_without_pollers = 1;
797
+ p->kicked_without_pollers = true;
736
798
  GPR_TIMER_END("pollset_kick_ext.broadcast", 0);
737
799
  } else if (gpr_tls_get(&g_current_thread_worker) !=
738
800
  (intptr_t)specific_worker) {
739
801
  GPR_TIMER_MARK("different_thread_worker", 0);
740
802
  if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) {
741
- specific_worker->reevaluate_polling_on_wakeup = 1;
803
+ specific_worker->reevaluate_polling_on_wakeup = true;
742
804
  }
743
- specific_worker->kicked_specifically = 1;
744
- grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
805
+ specific_worker->kicked_specifically = true;
806
+ kick_append_error(&error,
807
+ grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd));
745
808
  } else if ((flags & GRPC_POLLSET_CAN_KICK_SELF) != 0) {
746
809
  GPR_TIMER_MARK("kick_yoself", 0);
747
810
  if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) {
748
- specific_worker->reevaluate_polling_on_wakeup = 1;
811
+ specific_worker->reevaluate_polling_on_wakeup = true;
749
812
  }
750
- specific_worker->kicked_specifically = 1;
751
- grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
813
+ specific_worker->kicked_specifically = true;
814
+ kick_append_error(&error,
815
+ grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd));
752
816
  }
753
817
  } else if (gpr_tls_get(&g_current_thread_poller) != (intptr_t)p) {
754
818
  GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0);
@@ -769,39 +833,41 @@ static void pollset_kick_ext(grpc_pollset *p,
769
833
  if (specific_worker != NULL) {
770
834
  GPR_TIMER_MARK("finally_kick", 0);
771
835
  push_back_worker(p, specific_worker);
772
- grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
836
+ kick_append_error(
837
+ &error, grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd));
773
838
  }
774
839
  } else {
775
840
  GPR_TIMER_MARK("kicked_no_pollers", 0);
776
- p->kicked_without_pollers = 1;
841
+ p->kicked_without_pollers = true;
777
842
  }
778
843
  }
779
844
 
780
845
  GPR_TIMER_END("pollset_kick_ext", 0);
846
+ return error;
781
847
  }
782
848
 
783
- static void pollset_kick(grpc_pollset *p,
784
- grpc_pollset_worker *specific_worker) {
785
- pollset_kick_ext(p, specific_worker, 0);
849
+ static grpc_error *pollset_kick(grpc_pollset *p,
850
+ grpc_pollset_worker *specific_worker) {
851
+ return pollset_kick_ext(p, specific_worker, 0);
786
852
  }
787
853
 
788
854
  /* global state management */
789
855
 
790
- static void pollset_global_init(void) {
856
+ static grpc_error *pollset_global_init(void) {
791
857
  gpr_tls_init(&g_current_thread_poller);
792
858
  gpr_tls_init(&g_current_thread_worker);
793
- grpc_wakeup_fd_global_init();
794
- grpc_wakeup_fd_init(&grpc_global_wakeup_fd);
859
+ return grpc_wakeup_fd_init(&grpc_global_wakeup_fd);
795
860
  }
796
861
 
797
862
  static void pollset_global_shutdown(void) {
798
863
  grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd);
799
864
  gpr_tls_destroy(&g_current_thread_poller);
800
865
  gpr_tls_destroy(&g_current_thread_worker);
801
- grpc_wakeup_fd_global_destroy();
802
866
  }
803
867
 
804
- static void kick_poller(void) { grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd); }
868
+ static grpc_error *kick_poller(void) {
869
+ return grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd);
870
+ }
805
871
 
806
872
  /* main interface */
807
873
 
@@ -864,14 +930,23 @@ static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
864
930
  static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) {
865
931
  GPR_ASSERT(grpc_closure_list_empty(pollset->idle_jobs));
866
932
  pollset->vtable->finish_shutdown(pollset);
867
- grpc_exec_ctx_enqueue(exec_ctx, pollset->shutdown_done, true, NULL);
933
+ grpc_exec_ctx_sched(exec_ctx, pollset->shutdown_done, GRPC_ERROR_NONE, NULL);
934
+ }
935
+
936
+ static void work_combine_error(grpc_error **composite, grpc_error *error) {
937
+ if (error == GRPC_ERROR_NONE) return;
938
+ if (*composite == GRPC_ERROR_NONE) {
939
+ *composite = GRPC_ERROR_CREATE("pollset_work");
940
+ }
941
+ *composite = grpc_error_add_child(*composite, error);
868
942
  }
869
943
 
870
- static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
871
- grpc_pollset_worker **worker_hdl, gpr_timespec now,
872
- gpr_timespec deadline) {
944
+ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
945
+ grpc_pollset_worker **worker_hdl,
946
+ gpr_timespec now, gpr_timespec deadline) {
873
947
  grpc_pollset_worker worker;
874
948
  *worker_hdl = &worker;
949
+ grpc_error *error = GRPC_ERROR_NONE;
875
950
 
876
951
  /* pollset->mu already held */
877
952
  int added_worker = 0;
@@ -887,7 +962,10 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
887
962
  pollset->local_wakeup_cache = worker.wakeup_fd->next;
888
963
  } else {
889
964
  worker.wakeup_fd = gpr_malloc(sizeof(*worker.wakeup_fd));
890
- grpc_wakeup_fd_init(&worker.wakeup_fd->fd);
965
+ error = grpc_wakeup_fd_init(&worker.wakeup_fd->fd);
966
+ if (error != GRPC_ERROR_NONE) {
967
+ return error;
968
+ }
891
969
  }
892
970
  worker.kicked_specifically = 0;
893
971
  /* If there's work waiting for the pollset to be idle, and the
@@ -924,8 +1002,9 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
924
1002
  }
925
1003
  gpr_tls_set(&g_current_thread_poller, (intptr_t)pollset);
926
1004
  GPR_TIMER_BEGIN("maybe_work_and_unlock", 0);
927
- pollset->vtable->maybe_work_and_unlock(exec_ctx, pollset, &worker,
928
- deadline, now);
1005
+ work_combine_error(&error,
1006
+ pollset->vtable->maybe_work_and_unlock(
1007
+ exec_ctx, pollset, &worker, deadline, now));
929
1008
  GPR_TIMER_END("maybe_work_and_unlock", 0);
930
1009
  locked = 0;
931
1010
  gpr_tls_set(&g_current_thread_poller, 0);
@@ -987,6 +1066,7 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
987
1066
  }
988
1067
  *worker_hdl = NULL;
989
1068
  GPR_TIMER_END("pollset_work", 0);
1069
+ return error;
990
1070
  }
991
1071
 
992
1072
  static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
@@ -1035,7 +1115,7 @@ typedef struct grpc_unary_promote_args {
1035
1115
  } grpc_unary_promote_args;
1036
1116
 
1037
1117
  static void basic_do_promote(grpc_exec_ctx *exec_ctx, void *args,
1038
- bool success) {
1118
+ grpc_error *error) {
1039
1119
  grpc_unary_promote_args *up_args = args;
1040
1120
  const grpc_pollset_vtable *original_vtable = up_args->original_vtable;
1041
1121
  grpc_pollset *pollset = up_args->pollset;
@@ -1137,7 +1217,8 @@ static void basic_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1137
1217
  up_args->promotion_closure.cb = basic_do_promote;
1138
1218
  up_args->promotion_closure.cb_arg = up_args;
1139
1219
 
1140
- grpc_closure_list_add(&pollset->idle_jobs, &up_args->promotion_closure, 1);
1220
+ grpc_closure_list_append(&pollset->idle_jobs, &up_args->promotion_closure,
1221
+ GRPC_ERROR_NONE);
1141
1222
  pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST);
1142
1223
 
1143
1224
  exit:
@@ -1146,11 +1227,9 @@ exit:
1146
1227
  }
1147
1228
  }
1148
1229
 
1149
- static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
1150
- grpc_pollset *pollset,
1151
- grpc_pollset_worker *worker,
1152
- gpr_timespec deadline,
1153
- gpr_timespec now) {
1230
+ static grpc_error *basic_pollset_maybe_work_and_unlock(
1231
+ grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker,
1232
+ gpr_timespec deadline, gpr_timespec now) {
1154
1233
  #define POLLOUT_CHECK (POLLOUT | POLLHUP | POLLERR)
1155
1234
  #define POLLIN_CHECK (POLLIN | POLLHUP | POLLERR)
1156
1235
 
@@ -1160,6 +1239,7 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
1160
1239
  int timeout;
1161
1240
  int r;
1162
1241
  nfds_t nfds;
1242
+ grpc_error *error = GRPC_ERROR_NONE;
1163
1243
 
1164
1244
  fd = pollset->data.ptr;
1165
1245
  if (fd && fd_is_orphaned(fd)) {
@@ -1200,33 +1280,37 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
1200
1280
 
1201
1281
  if (r < 0) {
1202
1282
  if (errno != EINTR) {
1203
- gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
1283
+ work_combine_error(&error, GRPC_OS_ERROR(errno, "poll"));
1204
1284
  }
1205
1285
  if (fd) {
1206
- fd_end_poll(exec_ctx, &fd_watcher, 0, 0);
1286
+ fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
1207
1287
  }
1208
1288
  } else if (r == 0) {
1209
1289
  if (fd) {
1210
- fd_end_poll(exec_ctx, &fd_watcher, 0, 0);
1290
+ fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
1211
1291
  }
1212
1292
  } else {
1213
1293
  if (pfd[0].revents & POLLIN_CHECK) {
1214
- grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd);
1294
+ work_combine_error(&error,
1295
+ grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd));
1215
1296
  }
1216
1297
  if (pfd[1].revents & POLLIN_CHECK) {
1217
- grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd);
1298
+ work_combine_error(&error,
1299
+ grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd));
1218
1300
  }
1219
1301
  if (nfds > 2) {
1220
1302
  fd_end_poll(exec_ctx, &fd_watcher, pfd[2].revents & POLLIN_CHECK,
1221
- pfd[2].revents & POLLOUT_CHECK);
1303
+ pfd[2].revents & POLLOUT_CHECK, pollset);
1222
1304
  } else if (fd) {
1223
- fd_end_poll(exec_ctx, &fd_watcher, 0, 0);
1305
+ fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
1224
1306
  }
1225
1307
  }
1226
1308
 
1227
1309
  if (fd) {
1228
1310
  GRPC_FD_UNREF(fd, "basicpoll_begin");
1229
1311
  }
1312
+
1313
+ return error;
1230
1314
  }
1231
1315
 
1232
1316
  static void basic_pollset_destroy(grpc_pollset *pollset) {
@@ -1287,7 +1371,7 @@ exit:
1287
1371
  }
1288
1372
  }
1289
1373
 
1290
- static void multipoll_with_poll_pollset_maybe_work_and_unlock(
1374
+ static grpc_error *multipoll_with_poll_pollset_maybe_work_and_unlock(
1291
1375
  grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker,
1292
1376
  gpr_timespec deadline, gpr_timespec now) {
1293
1377
  #define POLLOUT_CHECK (POLLOUT | POLLHUP | POLLERR)
@@ -1301,6 +1385,7 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock(
1301
1385
  /* TODO(ctiller): inline some elements to avoid an allocation */
1302
1386
  grpc_fd_watcher *watchers;
1303
1387
  struct pollfd *pfds;
1388
+ grpc_error *error = GRPC_ERROR_NONE;
1304
1389
 
1305
1390
  h = pollset->data.ptr;
1306
1391
  timeout = poll_deadline_to_millis_timeout(deadline, now);
@@ -1353,34 +1438,38 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock(
1353
1438
 
1354
1439
  if (r < 0) {
1355
1440
  if (errno != EINTR) {
1356
- gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
1441
+ work_combine_error(&error, GRPC_OS_ERROR(errno, "poll"));
1357
1442
  }
1358
1443
  for (i = 2; i < pfd_count; i++) {
1359
- fd_end_poll(exec_ctx, &watchers[i], 0, 0);
1444
+ fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
1360
1445
  }
1361
1446
  } else if (r == 0) {
1362
1447
  for (i = 2; i < pfd_count; i++) {
1363
- fd_end_poll(exec_ctx, &watchers[i], 0, 0);
1448
+ fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
1364
1449
  }
1365
1450
  } else {
1366
1451
  if (pfds[0].revents & POLLIN_CHECK) {
1367
- grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd);
1452
+ work_combine_error(&error,
1453
+ grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd));
1368
1454
  }
1369
1455
  if (pfds[1].revents & POLLIN_CHECK) {
1370
- grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd);
1456
+ work_combine_error(&error,
1457
+ grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd));
1371
1458
  }
1372
1459
  for (i = 2; i < pfd_count; i++) {
1373
1460
  if (watchers[i].fd == NULL) {
1374
- fd_end_poll(exec_ctx, &watchers[i], 0, 0);
1461
+ fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
1375
1462
  continue;
1376
1463
  }
1377
1464
  fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN_CHECK,
1378
- pfds[i].revents & POLLOUT_CHECK);
1465
+ pfds[i].revents & POLLOUT_CHECK, pollset);
1379
1466
  }
1380
1467
  }
1381
1468
 
1382
1469
  gpr_free(pfds);
1383
1470
  gpr_free(watchers);
1471
+
1472
+ return error;
1384
1473
  }
1385
1474
 
1386
1475
  static void multipoll_with_poll_pollset_finish_shutdown(grpc_pollset *pollset) {
@@ -1451,20 +1540,31 @@ static void poll_become_multipoller(grpc_exec_ctx *exec_ctx,
1451
1540
  #include "src/core/lib/profiling/timers.h"
1452
1541
  #include "src/core/lib/support/block_annotate.h"
1453
1542
 
1454
- static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure **st) {
1543
+ static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure **st,
1544
+ grpc_pollset *read_notifier_pollset) {
1455
1545
  /* only one set_ready can be active at once (but there may be a racing
1456
1546
  notify_on) */
1457
1547
  gpr_mu_lock(&fd->mu);
1458
1548
  set_ready_locked(exec_ctx, fd, st);
1549
+
1550
+ /* A non-NULL read_notifier_pollset means that the fd is readable. */
1551
+ if (read_notifier_pollset != NULL) {
1552
+ /* Note: Since the fd might be a part of multiple pollsets, this might be
1553
+ * called multiple times (for each time the fd becomes readable) and it is
1554
+ * okay to set the fd's read-notifier pollset to anyone of these pollsets */
1555
+ set_read_notifier_pollset_locked(exec_ctx, fd, read_notifier_pollset);
1556
+ }
1557
+
1459
1558
  gpr_mu_unlock(&fd->mu);
1460
1559
  }
1461
1560
 
1462
- static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
1463
- set_ready(exec_ctx, fd, &fd->read_closure);
1561
+ static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1562
+ grpc_pollset *notifier_pollset) {
1563
+ set_ready(exec_ctx, fd, &fd->read_closure, notifier_pollset);
1464
1564
  }
1465
1565
 
1466
1566
  static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
1467
- set_ready(exec_ctx, fd, &fd->write_closure);
1567
+ set_ready(exec_ctx, fd, &fd->write_closure, NULL);
1468
1568
  }
1469
1569
 
1470
1570
  struct epoll_fd_list {
@@ -1556,11 +1656,11 @@ static void finally_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1556
1656
  }
1557
1657
  }
1558
1658
  }
1559
- fd_end_poll(exec_ctx, &watcher, 0, 0);
1659
+ fd_end_poll(exec_ctx, &watcher, 0, 0, NULL);
1560
1660
  }
1561
1661
 
1562
1662
  static void perform_delayed_add(grpc_exec_ctx *exec_ctx, void *arg,
1563
- bool iomgr_status) {
1663
+ grpc_error *error) {
1564
1664
  delayed_add *da = arg;
1565
1665
 
1566
1666
  if (!fd_is_orphaned(da->fd)) {
@@ -1573,7 +1673,8 @@ static void perform_delayed_add(grpc_exec_ctx *exec_ctx, void *arg,
1573
1673
  /* We don't care about this pollset anymore. */
1574
1674
  if (da->pollset->in_flight_cbs == 0 && !da->pollset->called_shutdown) {
1575
1675
  da->pollset->called_shutdown = 1;
1576
- grpc_exec_ctx_enqueue(exec_ctx, da->pollset->shutdown_done, true, NULL);
1676
+ grpc_exec_ctx_sched(exec_ctx, da->pollset->shutdown_done, GRPC_ERROR_NONE,
1677
+ NULL);
1577
1678
  }
1578
1679
  }
1579
1680
  gpr_mu_unlock(&da->pollset->mu);
@@ -1597,14 +1698,14 @@ static void multipoll_with_epoll_pollset_add_fd(grpc_exec_ctx *exec_ctx,
1597
1698
  GRPC_FD_REF(fd, "delayed_add");
1598
1699
  grpc_closure_init(&da->closure, perform_delayed_add, da);
1599
1700
  pollset->in_flight_cbs++;
1600
- grpc_exec_ctx_enqueue(exec_ctx, &da->closure, true, NULL);
1701
+ grpc_exec_ctx_sched(exec_ctx, &da->closure, GRPC_ERROR_NONE, NULL);
1601
1702
  }
1602
1703
  }
1603
1704
 
1604
1705
  /* TODO(klempner): We probably want to turn this down a bit */
1605
1706
  #define GRPC_EPOLL_MAX_EVENTS 1000
1606
1707
 
1607
- static void multipoll_with_epoll_pollset_maybe_work_and_unlock(
1708
+ static grpc_error *multipoll_with_epoll_pollset_maybe_work_and_unlock(
1608
1709
  grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker,
1609
1710
  gpr_timespec deadline, gpr_timespec now) {
1610
1711
  struct epoll_event ep_ev[GRPC_EPOLL_MAX_EVENTS];
@@ -1613,6 +1714,7 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock(
1613
1714
  epoll_hdr *h = pollset->data.ptr;
1614
1715
  int timeout_ms;
1615
1716
  struct pollfd pfds[2];
1717
+ grpc_error *error = GRPC_ERROR_NONE;
1616
1718
 
1617
1719
  /* If you want to ignore epoll's ability to sanely handle parallel pollers,
1618
1720
  * for a more apples-to-apples performance comparison with poll, add a
@@ -1641,13 +1743,14 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock(
1641
1743
 
1642
1744
  if (poll_rv < 0) {
1643
1745
  if (errno != EINTR) {
1644
- gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
1746
+ work_combine_error(&error, GRPC_OS_ERROR(errno, "poll"));
1645
1747
  }
1646
1748
  } else if (poll_rv == 0) {
1647
1749
  /* do nothing */
1648
1750
  } else {
1649
1751
  if (pfds[0].revents) {
1650
- grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd);
1752
+ work_combine_error(&error,
1753
+ grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd));
1651
1754
  }
1652
1755
  if (pfds[1].revents) {
1653
1756
  do {
@@ -1655,7 +1758,7 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock(
1655
1758
  ep_rv = epoll_wait(h->epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0);
1656
1759
  if (ep_rv < 0) {
1657
1760
  if (errno != EINTR) {
1658
- gpr_log(GPR_ERROR, "epoll_wait() failed: %s", strerror(errno));
1761
+ work_combine_error(&error, GRPC_OS_ERROR(errno, "epoll_wait"));
1659
1762
  }
1660
1763
  } else {
1661
1764
  int i;
@@ -1667,10 +1770,11 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock(
1667
1770
  int read_ev = ep_ev[i].events & (EPOLLIN | EPOLLPRI);
1668
1771
  int write_ev = ep_ev[i].events & EPOLLOUT;
1669
1772
  if (fd == NULL) {
1670
- grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd);
1773
+ work_combine_error(&error, grpc_wakeup_fd_consume_wakeup(
1774
+ &grpc_global_wakeup_fd));
1671
1775
  } else {
1672
1776
  if (read_ev || cancel) {
1673
- fd_become_readable(exec_ctx, fd);
1777
+ fd_become_readable(exec_ctx, fd, pollset);
1674
1778
  }
1675
1779
  if (write_ev || cancel) {
1676
1780
  fd_become_writable(exec_ctx, fd);
@@ -1681,6 +1785,7 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock(
1681
1785
  } while (ep_rv == GRPC_EPOLL_MAX_EVENTS);
1682
1786
  }
1683
1787
  }
1788
+ return error;
1684
1789
  }
1685
1790
 
1686
1791
  static void multipoll_with_epoll_pollset_finish_shutdown(
@@ -1897,8 +2002,10 @@ static const grpc_event_engine_vtable vtable = {
1897
2002
  .fd_wrapped_fd = fd_wrapped_fd,
1898
2003
  .fd_orphan = fd_orphan,
1899
2004
  .fd_shutdown = fd_shutdown,
2005
+ .fd_is_shutdown = fd_is_shutdown,
1900
2006
  .fd_notify_on_read = fd_notify_on_read,
1901
2007
  .fd_notify_on_write = fd_notify_on_write,
2008
+ .fd_get_read_notifier_pollset = fd_get_read_notifier_pollset,
1902
2009
 
1903
2010
  .pollset_init = pollset_init,
1904
2011
  .pollset_shutdown = pollset_shutdown,