grpc 1.1.2 → 1.2.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1257 -404
  3. data/etc/roots.pem +189 -102
  4. data/include/grpc/census.h +7 -7
  5. data/include/grpc/compression.h +4 -4
  6. data/include/grpc/grpc.h +13 -7
  7. data/include/grpc/impl/codegen/atm_gcc_atomic.h +26 -9
  8. data/include/grpc/impl/codegen/grpc_types.h +39 -30
  9. data/include/grpc/impl/codegen/slice.h +24 -6
  10. data/include/grpc/impl/codegen/sync.h +8 -0
  11. data/include/grpc/load_reporting.h +63 -0
  12. data/include/grpc/slice.h +37 -1
  13. data/include/grpc/slice_buffer.h +7 -0
  14. data/include/grpc/support/alloc.h +3 -0
  15. data/include/grpc/support/useful.h +3 -0
  16. data/src/core/ext/census/gen/census.pb.h +1 -1
  17. data/src/core/ext/census/gen/trace_context.pb.c +9 -36
  18. data/src/core/ext/census/gen/trace_context.pb.h +20 -26
  19. data/src/core/ext/census/grpc_filter.c +3 -5
  20. data/src/core/ext/census/trace_context.c +1 -1
  21. data/src/core/ext/census/trace_context.h +3 -0
  22. data/src/core/ext/census/trace_label.h +61 -0
  23. data/src/core/ext/census/trace_propagation.h +63 -0
  24. data/src/core/ext/census/trace_status.h +45 -0
  25. data/src/core/ext/census/trace_string.h +50 -0
  26. data/src/core/ext/census/tracing.c +31 -11
  27. data/src/core/ext/census/tracing.h +124 -0
  28. data/src/core/ext/client_channel/client_channel.c +456 -368
  29. data/src/core/ext/client_channel/client_channel.h +4 -0
  30. data/src/core/ext/client_channel/client_channel_plugin.c +6 -1
  31. data/src/core/ext/client_channel/connector.c +3 -3
  32. data/src/core/ext/client_channel/connector.h +4 -3
  33. data/src/core/ext/client_channel/http_connect_handshaker.c +62 -72
  34. data/src/core/ext/client_channel/http_connect_handshaker.h +7 -10
  35. data/src/core/ext/client_channel/http_proxy.c +125 -0
  36. data/src/core/ext/client_channel/http_proxy.h +39 -0
  37. data/src/core/ext/client_channel/lb_policy.c +56 -35
  38. data/src/core/ext/client_channel/lb_policy.h +46 -39
  39. data/src/core/ext/client_channel/lb_policy_factory.h +1 -0
  40. data/src/core/ext/client_channel/parse_address.c +32 -6
  41. data/src/core/ext/client_channel/proxy_mapper.c +63 -0
  42. data/src/core/ext/client_channel/proxy_mapper.h +89 -0
  43. data/src/core/ext/client_channel/proxy_mapper_registry.c +133 -0
  44. data/src/core/ext/client_channel/proxy_mapper_registry.h +59 -0
  45. data/src/core/ext/client_channel/resolver.c +16 -9
  46. data/src/core/ext/client_channel/resolver.h +23 -12
  47. data/src/core/ext/client_channel/resolver_factory.h +1 -0
  48. data/src/core/ext/client_channel/resolver_registry.c +15 -11
  49. data/src/core/ext/client_channel/resolver_registry.h +5 -3
  50. data/src/core/ext/client_channel/subchannel.c +44 -27
  51. data/src/core/ext/client_channel/subchannel.h +6 -2
  52. data/src/core/ext/client_channel/uri_parser.c +26 -14
  53. data/src/core/ext/client_channel/uri_parser.h +3 -1
  54. data/src/core/ext/lb_policy/grpclb/grpclb.c +220 -209
  55. data/src/core/ext/lb_policy/grpclb/grpclb_channel.h +56 -0
  56. data/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c +107 -0
  57. data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +3 -6
  58. data/src/core/ext/lb_policy/pick_first/pick_first.c +71 -116
  59. data/src/core/ext/lb_policy/round_robin/round_robin.c +52 -67
  60. data/src/core/ext/load_reporting/load_reporting.c +20 -0
  61. data/src/core/ext/load_reporting/load_reporting.h +1 -16
  62. data/src/core/ext/load_reporting/load_reporting_filter.c +28 -54
  63. data/src/core/ext/resolver/dns/native/dns_resolver.c +31 -45
  64. data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +20 -29
  65. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +11 -8
  66. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +11 -2
  67. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +143 -46
  68. data/src/core/ext/transport/chttp2/server/chttp2_server.c +12 -50
  69. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +1 -1
  70. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +1 -1
  71. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +7 -7
  72. data/src/core/ext/transport/chttp2/transport/bin_encoder.c +1 -2
  73. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -2
  74. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
  75. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +606 -374
  76. data/src/core/ext/transport/chttp2/transport/frame_ping.c +17 -5
  77. data/src/core/ext/transport/chttp2/transport/frame_ping.h +2 -2
  78. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +9 -13
  79. data/src/core/ext/transport/chttp2/transport/frame_settings.c +12 -11
  80. data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -1
  81. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +5 -6
  82. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +100 -53
  83. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -2
  84. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +126 -70
  85. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +13 -7
  86. data/src/core/ext/transport/chttp2/transport/hpack_table.c +22 -19
  87. data/src/core/ext/transport/chttp2/transport/hpack_table.h +6 -6
  88. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +23 -11
  89. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -2
  90. data/src/core/ext/transport/chttp2/transport/internal.h +169 -42
  91. data/src/core/ext/transport/chttp2/transport/parsing.c +98 -41
  92. data/src/core/ext/transport/chttp2/transport/stream_lists.c +29 -14
  93. data/src/core/ext/transport/chttp2/transport/writing.c +137 -15
  94. data/src/core/lib/channel/channel_stack.c +14 -44
  95. data/src/core/lib/channel/channel_stack.h +10 -17
  96. data/src/core/lib/channel/channel_stack_builder.c +2 -3
  97. data/src/core/lib/channel/compress_filter.c +54 -46
  98. data/src/core/lib/channel/connected_channel.c +4 -4
  99. data/src/core/lib/channel/connected_channel.h +5 -0
  100. data/src/core/lib/channel/context.h +3 -0
  101. data/src/core/lib/channel/deadline_filter.c +61 -61
  102. data/src/core/lib/channel/deadline_filter.h +8 -5
  103. data/src/core/lib/channel/handshaker.c +47 -7
  104. data/src/core/lib/channel/handshaker.h +21 -3
  105. data/src/core/lib/channel/http_client_filter.c +149 -99
  106. data/src/core/lib/channel/http_server_filter.c +163 -147
  107. data/src/core/lib/channel/message_size_filter.c +15 -10
  108. data/src/core/lib/compression/algorithm_metadata.h +4 -4
  109. data/src/core/lib/compression/compression.c +17 -23
  110. data/src/core/lib/http/httpcli.c +3 -2
  111. data/src/core/lib/http/httpcli.h +2 -1
  112. data/src/core/lib/http/httpcli_security_connector.c +2 -3
  113. data/src/core/lib/http/parser.c +2 -2
  114. data/src/core/lib/iomgr/closure.c +6 -3
  115. data/src/core/lib/iomgr/closure.h +4 -2
  116. data/src/core/lib/iomgr/combiner.c +35 -5
  117. data/src/core/lib/iomgr/combiner.h +21 -2
  118. data/src/core/lib/iomgr/endpoint.c +3 -2
  119. data/src/core/lib/iomgr/endpoint.h +3 -2
  120. data/src/core/lib/iomgr/error.c +60 -94
  121. data/src/core/lib/iomgr/error.h +7 -10
  122. data/src/core/lib/iomgr/error_internal.h +54 -0
  123. data/src/core/lib/iomgr/ev_epoll_linux.c +253 -109
  124. data/src/core/lib/iomgr/ev_poll_posix.c +61 -29
  125. data/src/core/lib/iomgr/ev_posix.c +7 -8
  126. data/src/core/lib/iomgr/ev_posix.h +4 -4
  127. data/src/core/lib/iomgr/exec_ctx.c +11 -6
  128. data/src/core/lib/iomgr/exec_ctx.h +11 -14
  129. data/src/core/lib/iomgr/executor.c +2 -2
  130. data/src/core/lib/iomgr/load_file.c +1 -1
  131. data/src/core/lib/iomgr/network_status_tracker.c +5 -81
  132. data/src/core/lib/iomgr/pollset.h +1 -3
  133. data/src/core/lib/iomgr/pollset_set.h +2 -1
  134. data/src/core/lib/iomgr/pollset_set_uv.c +2 -1
  135. data/src/core/lib/iomgr/pollset_set_windows.c +2 -1
  136. data/src/core/lib/iomgr/pollset_uv.c +25 -11
  137. data/src/core/lib/iomgr/pollset_windows.c +0 -11
  138. data/src/core/lib/iomgr/resolve_address_uv.c +50 -2
  139. data/src/core/lib/iomgr/resource_quota.c +41 -11
  140. data/src/core/lib/iomgr/resource_quota.h +6 -0
  141. data/src/core/lib/iomgr/sockaddr_utils.c +33 -17
  142. data/src/core/lib/iomgr/sockaddr_utils.h +4 -0
  143. data/src/core/lib/iomgr/tcp_client_posix.c +2 -3
  144. data/src/core/lib/iomgr/tcp_client_uv.c +1 -3
  145. data/src/core/lib/iomgr/tcp_client_windows.c +21 -6
  146. data/src/core/lib/iomgr/tcp_posix.c +4 -5
  147. data/src/core/lib/iomgr/tcp_server_posix.c +269 -94
  148. data/src/core/lib/iomgr/tcp_server_windows.c +1 -1
  149. data/src/core/lib/iomgr/tcp_uv.c +11 -5
  150. data/src/core/lib/iomgr/tcp_windows.c +20 -7
  151. data/src/core/lib/iomgr/timer_generic.c +15 -22
  152. data/src/core/lib/iomgr/timer_generic.h +1 -1
  153. data/src/core/lib/iomgr/timer_uv.c +10 -6
  154. data/src/core/lib/iomgr/timer_uv.h +1 -1
  155. data/src/core/lib/iomgr/udp_server.c +45 -6
  156. data/src/core/lib/iomgr/udp_server.h +7 -1
  157. data/src/core/lib/iomgr/unix_sockets_posix.c +11 -1
  158. data/src/core/lib/json/json.c +1 -2
  159. data/src/core/lib/profiling/basic_timers.c +17 -3
  160. data/src/core/lib/security/context/security_context.c +3 -10
  161. data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -8
  162. data/src/core/lib/security/credentials/credentials.c +48 -2
  163. data/src/core/lib/security/credentials/credentials.h +13 -0
  164. data/src/core/lib/security/credentials/credentials_metadata.c +1 -2
  165. data/src/core/lib/security/credentials/fake/fake_credentials.c +6 -8
  166. data/src/core/lib/security/credentials/fake/fake_credentials.h +15 -0
  167. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +3 -3
  168. data/src/core/lib/security/credentials/iam/iam_credentials.c +1 -2
  169. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -2
  170. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +5 -8
  171. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
  172. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +3 -5
  173. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +15 -13
  174. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +2 -4
  175. data/src/core/lib/security/transport/client_auth_filter.c +72 -47
  176. data/src/core/lib/security/transport/lb_targets_info.c +70 -0
  177. data/src/core/lib/security/transport/lb_targets_info.h +47 -0
  178. data/src/core/lib/security/transport/secure_endpoint.c +3 -3
  179. data/src/core/lib/security/transport/security_connector.c +125 -28
  180. data/src/core/lib/security/transport/security_connector.h +4 -3
  181. data/src/core/lib/security/transport/security_handshaker.c +13 -9
  182. data/src/core/lib/security/transport/server_auth_filter.c +31 -40
  183. data/src/core/lib/security/util/b64.c +1 -1
  184. data/src/core/lib/slice/slice.c +110 -20
  185. data/src/core/lib/slice/slice_buffer.c +92 -39
  186. data/src/core/lib/{transport/mdstr_hash_table.c → slice/slice_hash_table.c} +40 -33
  187. data/src/core/lib/{transport/mdstr_hash_table.h → slice/slice_hash_table.h} +21 -21
  188. data/src/core/lib/slice/slice_intern.c +346 -0
  189. data/src/core/lib/slice/slice_internal.h +15 -0
  190. data/src/core/lib/slice/slice_string_helpers.c +5 -0
  191. data/src/core/lib/slice/slice_string_helpers.h +5 -0
  192. data/src/core/lib/support/alloc.c +26 -1
  193. data/src/core/lib/support/cmdline.c +2 -4
  194. data/src/core/lib/support/cpu_posix.c +2 -7
  195. data/src/core/lib/support/histogram.c +1 -2
  196. data/src/core/lib/support/log_posix.c +8 -4
  197. data/src/core/lib/support/spinlock.h +52 -0
  198. data/src/core/lib/support/subprocess_posix.c +1 -2
  199. data/src/core/lib/support/sync.c +7 -1
  200. data/src/core/lib/support/sync_posix.c +9 -0
  201. data/src/core/lib/support/time_windows.c +7 -1
  202. data/src/core/lib/surface/call.c +647 -629
  203. data/src/core/lib/surface/call.h +4 -1
  204. data/src/core/lib/surface/call_details.c +8 -2
  205. data/src/core/lib/surface/call_log_batch.c +17 -6
  206. data/src/core/lib/surface/channel.c +49 -59
  207. data/src/core/lib/surface/channel.h +5 -6
  208. data/src/core/lib/surface/completion_queue.c +16 -45
  209. data/src/core/lib/surface/completion_queue.h +0 -3
  210. data/src/core/lib/surface/init.c +6 -2
  211. data/src/core/lib/surface/init_secure.c +1 -1
  212. data/src/core/lib/surface/lame_client.c +14 -4
  213. data/src/core/lib/surface/server.c +79 -82
  214. data/src/core/lib/surface/validate_metadata.c +46 -15
  215. data/src/core/lib/surface/validate_metadata.h +43 -0
  216. data/src/core/lib/surface/version.c +2 -2
  217. data/src/core/lib/transport/bdp_estimator.c +104 -0
  218. data/src/core/lib/transport/bdp_estimator.h +76 -0
  219. data/src/core/lib/transport/connectivity_state.c +33 -13
  220. data/src/core/lib/transport/connectivity_state.h +15 -5
  221. data/src/core/lib/transport/error_utils.c +124 -0
  222. data/src/core/lib/transport/error_utils.h +56 -0
  223. data/src/core/{ext/transport/chttp2 → lib}/transport/http2_errors.h +18 -18
  224. data/src/core/lib/transport/metadata.c +259 -503
  225. data/src/core/lib/transport/metadata.h +69 -68
  226. data/src/core/lib/transport/metadata_batch.c +183 -63
  227. data/src/core/lib/transport/metadata_batch.h +50 -26
  228. data/src/core/lib/transport/pid_controller.c +28 -8
  229. data/src/core/lib/transport/pid_controller.h +15 -2
  230. data/src/core/lib/transport/service_config.c +21 -18
  231. data/src/core/lib/transport/service_config.h +5 -5
  232. data/src/core/lib/transport/static_metadata.c +753 -112
  233. data/src/core/lib/transport/static_metadata.h +403 -264
  234. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.c +18 -20
  235. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.h +9 -10
  236. data/src/core/lib/transport/timeout_encoding.c +11 -9
  237. data/src/core/lib/transport/timeout_encoding.h +3 -1
  238. data/src/core/lib/transport/transport.c +47 -87
  239. data/src/core/lib/transport/transport.h +20 -25
  240. data/src/core/lib/transport/transport_op_string.c +7 -19
  241. data/src/core/lib/tsi/fake_transport_security.c +2 -4
  242. data/src/core/lib/tsi/ssl_transport_security.c +7 -16
  243. data/src/core/lib/tsi/transport_security.c +2 -4
  244. data/src/ruby/ext/grpc/extconf.rb +4 -1
  245. data/src/ruby/ext/grpc/rb_byte_buffer.c +7 -0
  246. data/src/ruby/ext/grpc/rb_byte_buffer.h +3 -0
  247. data/src/ruby/ext/grpc/rb_call.c +47 -46
  248. data/src/ruby/ext/grpc/rb_channel.c +21 -6
  249. data/src/ruby/ext/grpc/rb_compression_options.c +9 -6
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -2
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +59 -8
  252. data/src/ruby/ext/grpc/rb_server.c +6 -4
  253. data/src/ruby/lib/grpc/generic/client_stub.rb +1 -1
  254. data/src/ruby/lib/grpc/version.rb +1 -1
  255. metadata +33 -9
@@ -124,7 +124,11 @@ typedef enum {
124
124
  /// filename that we were trying to read/write when this error occurred
125
125
  GRPC_ERROR_STR_FILENAME,
126
126
  /// which data was queued for writing when the error occurred
127
- GRPC_ERROR_STR_QUEUED_BUFFERS
127
+ GRPC_ERROR_STR_QUEUED_BUFFERS,
128
+ /// key associated with the error
129
+ GRPC_ERROR_STR_KEY,
130
+ /// value associated with the error
131
+ GRPC_ERROR_STR_VALUE,
128
132
  } grpc_error_strs;
129
133
 
130
134
  typedef enum {
@@ -133,15 +137,14 @@ typedef enum {
133
137
  } grpc_error_times;
134
138
 
135
139
  /// 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.
140
+ /// They are always even so that other code (particularly combiner locks,
141
+ /// polling engines) can safely use the lower bit for themselves.
138
142
 
139
143
  #define GRPC_ERROR_NONE ((grpc_error *)NULL)
140
144
  #define GRPC_ERROR_OOM ((grpc_error *)2)
141
145
  #define GRPC_ERROR_CANCELLED ((grpc_error *)4)
142
146
 
143
147
  const char *grpc_error_string(grpc_error *error);
144
- void grpc_error_free_string(const char *str);
145
148
 
146
149
  /// Create an error - but use GRPC_ERROR_CREATE instead
147
150
  grpc_error *grpc_error_create(const char *file, int line, const char *desc,
@@ -189,12 +192,6 @@ grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which,
189
192
  /// Caller does NOT own return value.
190
193
  const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which);
191
194
 
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
-
198
195
  /// Add a child error: an error that is believed to have contributed to this
199
196
  /// error occurring. Allows root causing high level errors from lower level
200
197
  /// errors that contributed to them.
@@ -0,0 +1,54 @@
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_INTERNAL_H
35
+ #define GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H
36
+
37
+ #include <inttypes.h>
38
+ #include <stdbool.h>
39
+
40
+ #include <grpc/support/avl.h>
41
+
42
+ struct grpc_error {
43
+ gpr_refcount refs;
44
+ gpr_avl ints;
45
+ gpr_avl strs;
46
+ gpr_avl times;
47
+ gpr_avl errs;
48
+ uintptr_t next_err;
49
+ gpr_atm error_string;
50
+ };
51
+
52
+ bool grpc_error_is_special(grpc_error *err);
53
+
54
+ #endif /* GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H */
@@ -68,7 +68,7 @@ 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 */
71
+ /* Uncomment the following to enable extra checks on poll_object operations */
72
72
  /* #define PO_DEBUG */
73
73
 
74
74
  static int grpc_wakeup_signal = -1;
@@ -140,23 +140,61 @@ struct grpc_fd {
140
140
  Ref/Unref by two to avoid altering the orphaned bit */
141
141
  gpr_atm refst;
142
142
 
143
- /* Indicates that the fd is shutdown and that any pending read/write closures
144
- should fail */
145
- bool shutdown;
143
+ /* Internally stores data of type (grpc_error *). If the FD is shutdown, this
144
+ contains reason for shutdown (i.e a pointer to grpc_error) ORed with
145
+ FD_SHUTDOWN_BIT. Since address allocations are word-aligned, the lower bit
146
+ of (grpc_error *) addresses is guaranteed to be zero. Even if the
147
+ (grpc_error *), is of special types like GRPC_ERROR_NONE, GRPC_ERROR_OOM
148
+ etc, the lower bit is guaranteed to be zero.
146
149
 
147
- /* The fd is either closed or we relinquished control of it. In either cases,
148
- this indicates that the 'fd' on this structure is no longer valid */
150
+ Once an fd is shutdown, any pending or future read/write closures on the
151
+ fd should fail */
152
+ gpr_atm shutdown_error;
153
+
154
+ /* The fd is either closed or we relinquished control of it. In either
155
+ cases, this indicates that the 'fd' on this structure is no longer
156
+ valid */
149
157
  bool orphaned;
150
158
 
151
- /* TODO: sreek - Move this to a lockfree implementation */
152
- grpc_closure *read_closure;
153
- grpc_closure *write_closure;
159
+ /* Closures to call when the fd is readable or writable respectively. These
160
+ fields contain one of the following values:
161
+ CLOSURE_READY : The fd has an I/O event of interest but there is no
162
+ closure yet to execute
163
+
164
+ CLOSURE_NOT_READY : The fd has no I/O event of interest
165
+
166
+ closure ptr : The closure to be executed when the fd has an I/O
167
+ event of interest
168
+
169
+ shutdown_error | FD_SHUTDOWN_BIT :
170
+ 'shutdown_error' field ORed with FD_SHUTDOWN_BIT.
171
+ This indicates that the fd is shutdown. Since all
172
+ memory allocations are word-aligned, the lower two
173
+ bits of the shutdown_error pointer are always 0. So
174
+ it is safe to OR these with FD_SHUTDOWN_BIT
175
+
176
+ Valid state transitions:
177
+
178
+ <closure ptr> <-----3------ CLOSURE_NOT_READY ----1----> CLOSURE_READY
179
+ | | ^ | ^ | |
180
+ | | | | | | |
181
+ | +--------------4----------+ 6 +---------2---------------+ |
182
+ | | |
183
+ | v |
184
+ +-----5-------> [shutdown_error | FD_SHUTDOWN_BIT] <----7---------+
185
+
186
+ For 1, 4 : See set_ready() function
187
+ For 2, 3 : See notify_on() function
188
+ For 5,6,7: See set_shutdown() function */
189
+ gpr_atm read_closure;
190
+ gpr_atm write_closure;
154
191
 
155
192
  struct grpc_fd *freelist_next;
156
193
  grpc_closure *on_done_closure;
157
194
 
158
- /* The pollset that last noticed that the fd is readable */
159
- grpc_pollset *read_notifier_pollset;
195
+ /* The pollset that last noticed that the fd is readable. The actual type
196
+ * stored in this is (grpc_pollset *) */
197
+ gpr_atm read_notifier_pollset;
160
198
 
161
199
  grpc_iomgr_object iomgr_object;
162
200
  };
@@ -179,8 +217,10 @@ static void fd_unref(grpc_fd *fd);
179
217
  static void fd_global_init(void);
180
218
  static void fd_global_shutdown(void);
181
219
 
182
- #define CLOSURE_NOT_READY ((grpc_closure *)0)
183
- #define CLOSURE_READY ((grpc_closure *)1)
220
+ #define CLOSURE_NOT_READY ((gpr_atm)0)
221
+ #define CLOSURE_READY ((gpr_atm)2)
222
+
223
+ #define FD_SHUTDOWN_BIT 1
184
224
 
185
225
  /*******************************************************************************
186
226
  * Polling island Declarations
@@ -321,7 +361,7 @@ gpr_atm g_epoll_sync;
321
361
  #endif /* defined(GRPC_TSAN) */
322
362
 
323
363
  static const grpc_closure_scheduler_vtable workqueue_scheduler_vtable = {
324
- workqueue_enqueue, workqueue_enqueue};
364
+ workqueue_enqueue, workqueue_enqueue, "workqueue"};
325
365
 
326
366
  static void pi_add_ref(polling_island *pi);
327
367
  static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi);
@@ -908,6 +948,11 @@ static void unref_by(grpc_fd *fd, int n) {
908
948
  fd_freelist = fd;
909
949
  grpc_iomgr_unregister_object(&fd->iomgr_object);
910
950
 
951
+ grpc_error *err = (grpc_error *)gpr_atm_acq_load(&fd->shutdown_error);
952
+ /* Clear the least significant bit if it set (in case fd was shutdown) */
953
+ err = (grpc_error *)((intptr_t)err & ~FD_SHUTDOWN_BIT);
954
+ GRPC_ERROR_UNREF(err);
955
+
911
956
  gpr_mu_unlock(&fd_freelist_mu);
912
957
  } else {
913
958
  GPR_ASSERT(old > n);
@@ -970,13 +1015,14 @@ static grpc_fd *fd_create(int fd, const char *name) {
970
1015
 
971
1016
  gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
972
1017
  new_fd->fd = fd;
973
- new_fd->shutdown = false;
1018
+ gpr_atm_no_barrier_store(&new_fd->shutdown_error, (gpr_atm)GRPC_ERROR_NONE);
974
1019
  new_fd->orphaned = false;
975
- new_fd->read_closure = CLOSURE_NOT_READY;
976
- new_fd->write_closure = CLOSURE_NOT_READY;
1020
+ gpr_atm_no_barrier_store(&new_fd->read_closure, CLOSURE_NOT_READY);
1021
+ gpr_atm_no_barrier_store(&new_fd->write_closure, CLOSURE_NOT_READY);
1022
+ gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
1023
+
977
1024
  new_fd->freelist_next = NULL;
978
1025
  new_fd->on_done_closure = NULL;
979
- new_fd->read_notifier_pollset = NULL;
980
1026
 
981
1027
  gpr_mu_unlock(&new_fd->po.mu);
982
1028
 
@@ -1058,98 +1104,206 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1058
1104
  GRPC_ERROR_UNREF(error);
1059
1105
  }
1060
1106
 
1061
- static grpc_error *fd_shutdown_error(bool shutdown) {
1062
- if (!shutdown) {
1063
- return GRPC_ERROR_NONE;
1064
- } else {
1065
- return GRPC_ERROR_CREATE("FD shutdown");
1107
+ static void notify_on(grpc_exec_ctx *exec_ctx, grpc_fd *fd, gpr_atm *state,
1108
+ grpc_closure *closure) {
1109
+ while (true) {
1110
+ /* Fast-path: CLOSURE_NOT_READY -> <closure>.
1111
+ The 'release' cas here matches the 'acquire' load in set_ready and
1112
+ set_shutdown ensuring that the closure (scheduled by set_ready or
1113
+ set_shutdown) happens-after the I/O event on the fd */
1114
+ if (gpr_atm_rel_cas(state, CLOSURE_NOT_READY, (gpr_atm)closure)) {
1115
+ return; /* Fast-path successful. Return */
1116
+ }
1117
+
1118
+ /* Slowpath. The 'acquire' load matches the 'release' cas in set_ready and
1119
+ set_shutdown */
1120
+ gpr_atm curr = gpr_atm_acq_load(state);
1121
+ switch (curr) {
1122
+ case CLOSURE_NOT_READY: {
1123
+ break; /* retry */
1124
+ }
1125
+
1126
+ case CLOSURE_READY: {
1127
+ /* Change the state to CLOSURE_NOT_READY. Schedule the closure if
1128
+ successful. If not, the state most likely transitioned to shutdown.
1129
+ We should retry.
1130
+
1131
+ This can be a no-barrier cas since the state is being transitioned to
1132
+ CLOSURE_NOT_READY; set_ready and set_shutdown do not schedule any
1133
+ closure when transitioning out of CLOSURE_NO_READY state (i.e there
1134
+ is no other code that needs to 'happen-after' this) */
1135
+ if (gpr_atm_no_barrier_cas(state, CLOSURE_READY, CLOSURE_NOT_READY)) {
1136
+ grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
1137
+ return; /* Slow-path successful. Return */
1138
+ }
1139
+
1140
+ break; /* retry */
1141
+ }
1142
+
1143
+ default: {
1144
+ /* 'curr' is either a closure or the fd is shutdown(in which case 'curr'
1145
+ contains a pointer to the shutdown-error). If the fd is shutdown,
1146
+ schedule the closure with the shutdown error */
1147
+ if ((curr & FD_SHUTDOWN_BIT) > 0) {
1148
+ grpc_error *shutdown_err = (grpc_error *)(curr & ~FD_SHUTDOWN_BIT);
1149
+ grpc_closure_sched(
1150
+ exec_ctx, closure,
1151
+ GRPC_ERROR_CREATE_REFERENCING("FD Shutdown", &shutdown_err, 1));
1152
+ return;
1153
+ }
1154
+
1155
+ /* There is already a closure!. This indicates a bug in the code */
1156
+ gpr_log(GPR_ERROR,
1157
+ "notify_on called with a previous callback still pending");
1158
+ abort();
1159
+ }
1160
+ }
1066
1161
  }
1162
+
1163
+ GPR_UNREACHABLE_CODE(return );
1067
1164
  }
1068
1165
 
1069
- static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1070
- grpc_closure **st, grpc_closure *closure) {
1071
- if (fd->shutdown) {
1072
- grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_CREATE("FD shutdown"));
1073
- } else if (*st == CLOSURE_NOT_READY) {
1074
- /* not ready ==> switch to a waiting state by setting the closure */
1075
- *st = closure;
1076
- } else if (*st == CLOSURE_READY) {
1077
- /* already ready ==> queue the closure to run immediately */
1078
- *st = CLOSURE_NOT_READY;
1079
- grpc_closure_sched(exec_ctx, closure, fd_shutdown_error(fd->shutdown));
1080
- } else {
1081
- /* upcallptr was set to a different closure. This is an error! */
1082
- gpr_log(GPR_ERROR,
1083
- "User called a notify_on function with a previous callback still "
1084
- "pending");
1085
- abort();
1166
+ static void set_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd, gpr_atm *state,
1167
+ grpc_error *shutdown_err) {
1168
+ /* Try the fast-path first (i.e expect the current value to be
1169
+ CLOSURE_NOT_READY */
1170
+ gpr_atm curr = CLOSURE_NOT_READY;
1171
+ gpr_atm new_state = (gpr_atm)shutdown_err | FD_SHUTDOWN_BIT;
1172
+
1173
+ while (true) {
1174
+ /* The 'release' cas here matches the 'acquire' load in notify_on to ensure
1175
+ that the closure it schedules 'happens-after' the set_shutdown is called
1176
+ on the fd */
1177
+ if (gpr_atm_rel_cas(state, curr, new_state)) {
1178
+ return; /* Fast-path successful. Return */
1179
+ }
1180
+
1181
+ /* Fallback to slowpath. This 'acquire' load matches the 'release' cas in
1182
+ notify_on and set_ready */
1183
+ curr = gpr_atm_acq_load(state);
1184
+ switch (curr) {
1185
+ case CLOSURE_READY: {
1186
+ break; /* retry */
1187
+ }
1188
+
1189
+ case CLOSURE_NOT_READY: {
1190
+ break; /* retry */
1191
+ }
1192
+
1193
+ default: {
1194
+ /* 'curr' is either a closure or the fd is already shutdown */
1195
+
1196
+ /* If fd is already shutdown, we are done */
1197
+ if ((curr & FD_SHUTDOWN_BIT) > 0) {
1198
+ return;
1199
+ }
1200
+
1201
+ /* Fd is not shutdown. Schedule the closure and move the state to
1202
+ shutdown state. The 'release' cas here matches the 'acquire' load in
1203
+ notify_on to ensure that the closure it schedules 'happens-after'
1204
+ the set_shutdown is called on the fd */
1205
+ if (gpr_atm_rel_cas(state, curr, new_state)) {
1206
+ grpc_closure_sched(
1207
+ exec_ctx, (grpc_closure *)curr,
1208
+ GRPC_ERROR_CREATE_REFERENCING("FD Shutdown", &shutdown_err, 1));
1209
+ return;
1210
+ }
1211
+
1212
+ /* 'curr' was a closure but now changed to a different state. We will
1213
+ have to retry */
1214
+ break;
1215
+ }
1216
+ }
1086
1217
  }
1218
+
1219
+ GPR_UNREACHABLE_CODE(return );
1087
1220
  }
1088
1221
 
1089
- /* returns 1 if state becomes not ready */
1090
- static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1091
- grpc_closure **st) {
1092
- if (*st == CLOSURE_READY) {
1093
- /* duplicate ready ==> ignore */
1094
- return 0;
1095
- } else if (*st == CLOSURE_NOT_READY) {
1096
- /* not ready, and not waiting ==> flag ready */
1097
- *st = CLOSURE_READY;
1098
- return 0;
1099
- } else {
1100
- /* waiting ==> queue closure */
1101
- grpc_closure_sched(exec_ctx, *st, fd_shutdown_error(fd->shutdown));
1102
- *st = CLOSURE_NOT_READY;
1103
- return 1;
1222
+ static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, gpr_atm *state) {
1223
+ /* Try an optimistic case first (i.e assume current state is
1224
+ CLOSURE_NOT_READY).
1225
+
1226
+ This 'release' cas matches the 'acquire' load in notify_on ensuring that
1227
+ any closure (scheduled by notify_on) 'happens-after' the return from
1228
+ epoll_pwait */
1229
+ if (gpr_atm_rel_cas(state, CLOSURE_NOT_READY, CLOSURE_READY)) {
1230
+ return; /* early out */
1231
+ }
1232
+
1233
+ /* The 'acquire' load here matches the 'release' cas in notify_on and
1234
+ set_shutdown */
1235
+ gpr_atm curr = gpr_atm_acq_load(state);
1236
+ switch (curr) {
1237
+ case CLOSURE_READY: {
1238
+ /* Already ready. We are done here */
1239
+ break;
1240
+ }
1241
+
1242
+ case CLOSURE_NOT_READY: {
1243
+ /* The state was not CLOSURE_NOT_READY when we checked initially at the
1244
+ beginning of this function but now it is CLOSURE_NOT_READY again.
1245
+ This is only possible if the state transitioned out of
1246
+ CLOSURE_NOT_READY to either CLOSURE_READY or <some closure> and then
1247
+ back to CLOSURE_NOT_READY again (i.e after we entered this function,
1248
+ the fd became "ready" and the necessary actions were already done).
1249
+ So there is no need to make the state CLOSURE_READY now */
1250
+ break;
1251
+ }
1252
+
1253
+ default: {
1254
+ /* 'curr' is either a closure or the fd is shutdown */
1255
+ if ((curr & FD_SHUTDOWN_BIT) > 0) {
1256
+ /* The fd is shutdown. Do nothing */
1257
+ } else if (gpr_atm_no_barrier_cas(state, curr, CLOSURE_NOT_READY)) {
1258
+ /* The cas above was no-barrier since the state is being transitioned to
1259
+ CLOSURE_NOT_READY; notify_on and set_shutdown do not schedule any
1260
+ closures when transitioning out of CLOSURE_NO_READY state (i.e there
1261
+ is no other code that needs to 'happen-after' this) */
1262
+
1263
+ grpc_closure_sched(exec_ctx, (grpc_closure *)curr, GRPC_ERROR_NONE);
1264
+ }
1265
+ /* else the state changed again (only possible by either a racing
1266
+ set_ready or set_shutdown functions. In both these cases, the closure
1267
+ would have been scheduled for execution. So we are done here */
1268
+ break;
1269
+ }
1104
1270
  }
1105
1271
  }
1106
1272
 
1107
1273
  static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
1108
1274
  grpc_fd *fd) {
1109
- grpc_pollset *notifier = NULL;
1110
-
1111
- gpr_mu_lock(&fd->po.mu);
1112
- notifier = fd->read_notifier_pollset;
1113
- gpr_mu_unlock(&fd->po.mu);
1114
-
1115
- return notifier;
1275
+ gpr_atm notifier = gpr_atm_acq_load(&fd->read_notifier_pollset);
1276
+ return (grpc_pollset *)notifier;
1116
1277
  }
1117
1278
 
1118
1279
  static bool fd_is_shutdown(grpc_fd *fd) {
1119
- gpr_mu_lock(&fd->po.mu);
1120
- const bool r = fd->shutdown;
1121
- gpr_mu_unlock(&fd->po.mu);
1122
- return r;
1280
+ grpc_error *err = (grpc_error *)gpr_atm_acq_load(&fd->shutdown_error);
1281
+ return (((intptr_t)err & FD_SHUTDOWN_BIT) > 0);
1123
1282
  }
1124
1283
 
1125
1284
  /* Might be called multiple times */
1126
- static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
1127
- gpr_mu_lock(&fd->po.mu);
1128
- /* Do the actual shutdown only once */
1129
- if (!fd->shutdown) {
1130
- fd->shutdown = true;
1131
-
1285
+ static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_error *why) {
1286
+ /* Store the shutdown error ORed with FD_SHUTDOWN_BIT in fd->shutdown_error */
1287
+ if (gpr_atm_rel_cas(&fd->shutdown_error, (gpr_atm)GRPC_ERROR_NONE,
1288
+ (gpr_atm)why | FD_SHUTDOWN_BIT)) {
1132
1289
  shutdown(fd->fd, SHUT_RDWR);
1133
- /* Flush any pending read and write closures. Since fd->shutdown is 'true'
1134
- at this point, the closures would be called with 'success = false' */
1135
- set_ready_locked(exec_ctx, fd, &fd->read_closure);
1136
- set_ready_locked(exec_ctx, fd, &fd->write_closure);
1290
+
1291
+ set_shutdown(exec_ctx, fd, &fd->read_closure, why);
1292
+ set_shutdown(exec_ctx, fd, &fd->write_closure, why);
1293
+ } else {
1294
+ /* Shutdown already called */
1295
+ GRPC_ERROR_UNREF(why);
1137
1296
  }
1138
- gpr_mu_unlock(&fd->po.mu);
1139
1297
  }
1140
1298
 
1141
1299
  static void fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1142
1300
  grpc_closure *closure) {
1143
- gpr_mu_lock(&fd->po.mu);
1144
- notify_on_locked(exec_ctx, fd, &fd->read_closure, closure);
1145
- gpr_mu_unlock(&fd->po.mu);
1301
+ notify_on(exec_ctx, fd, &fd->read_closure, closure);
1146
1302
  }
1147
1303
 
1148
1304
  static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1149
1305
  grpc_closure *closure) {
1150
- gpr_mu_lock(&fd->po.mu);
1151
- notify_on_locked(exec_ctx, fd, &fd->write_closure, closure);
1152
- gpr_mu_unlock(&fd->po.mu);
1306
+ notify_on(exec_ctx, fd, &fd->write_closure, closure);
1153
1307
  }
1154
1308
 
1155
1309
  static grpc_workqueue *fd_get_workqueue(grpc_fd *fd) {
@@ -1338,18 +1492,19 @@ static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
1338
1492
 
1339
1493
  static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1340
1494
  grpc_pollset *notifier) {
1341
- /* Need the fd->po.mu since we might be racing with fd_notify_on_read */
1342
- gpr_mu_lock(&fd->po.mu);
1343
- set_ready_locked(exec_ctx, fd, &fd->read_closure);
1344
- fd->read_notifier_pollset = notifier;
1345
- gpr_mu_unlock(&fd->po.mu);
1495
+ set_ready(exec_ctx, fd, &fd->read_closure);
1496
+
1497
+ /* Note, it is possible that fd_become_readable might be called twice with
1498
+ different 'notifier's when an fd becomes readable and it is in two epoll
1499
+ sets (This can happen briefly during polling island merges). In such cases
1500
+ it does not really matter which notifer is set as the read_notifier_pollset
1501
+ (They would both point to the same polling island anyway) */
1502
+ /* Use release store to match with acquire load in fd_get_read_notifier */
1503
+ gpr_atm_rel_store(&fd->read_notifier_pollset, (gpr_atm)notifier);
1346
1504
  }
1347
1505
 
1348
1506
  static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
1349
- /* Need the fd->po.mu since we might be racing with fd_notify_on_write */
1350
- gpr_mu_lock(&fd->po.mu);
1351
- set_ready_locked(exec_ctx, fd, &fd->write_closure);
1352
- gpr_mu_unlock(&fd->po.mu);
1507
+ set_ready(exec_ctx, fd, &fd->write_closure);
1353
1508
  }
1354
1509
 
1355
1510
  static void pollset_release_polling_island(grpc_exec_ctx *exec_ctx,
@@ -1400,16 +1555,6 @@ static void pollset_destroy(grpc_pollset *pollset) {
1400
1555
  gpr_mu_destroy(&pollset->po.mu);
1401
1556
  }
1402
1557
 
1403
- static void pollset_reset(grpc_pollset *pollset) {
1404
- GPR_ASSERT(pollset->shutting_down);
1405
- GPR_ASSERT(!pollset_has_workers(pollset));
1406
- pollset->shutting_down = false;
1407
- pollset->finish_shutdown_called = false;
1408
- pollset->kicked_without_pollers = false;
1409
- pollset->shutdown_done = NULL;
1410
- GPR_ASSERT(pollset->po.pi == NULL);
1411
- }
1412
-
1413
1558
  static bool maybe_do_workqueue_work(grpc_exec_ctx *exec_ctx,
1414
1559
  polling_island *pi) {
1415
1560
  if (gpr_mu_trylock(&pi->workqueue_read_mu)) {
@@ -1527,7 +1672,8 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
1527
1672
  append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
1528
1673
  err_desc);
1529
1674
  } else if (data_ptr == &pi->workqueue_wakeup_fd) {
1530
- append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
1675
+ append_error(error,
1676
+ grpc_wakeup_fd_consume_wakeup(&pi->workqueue_wakeup_fd),
1531
1677
  err_desc);
1532
1678
  maybe_do_workqueue_work(exec_ctx, pi);
1533
1679
  } else if (data_ptr == &polling_island_wakeup_fd) {
@@ -1741,7 +1887,7 @@ retry:
1741
1887
  (void *)pi_new, FD_FROM_PO(item)->fd, poll_obj_string(bag_type),
1742
1888
  (void *)bag);
1743
1889
  /* No need to lock 'pi_new' here since this is a new polling island
1744
- * and no one has a reference to it yet */
1890
+ and no one has a reference to it yet */
1745
1891
  polling_island_remove_all_fds_locked(pi_new, true, &error);
1746
1892
 
1747
1893
  /* Ref and unref so that the polling island gets deleted during unref
@@ -1846,13 +1992,12 @@ static grpc_pollset_set *pollset_set_create(void) {
1846
1992
  return pss;
1847
1993
  }
1848
1994
 
1849
- static void pollset_set_destroy(grpc_pollset_set *pss) {
1995
+ static void pollset_set_destroy(grpc_exec_ctx *exec_ctx,
1996
+ grpc_pollset_set *pss) {
1850
1997
  gpr_mu_destroy(&pss->po.mu);
1851
1998
 
1852
1999
  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);
2000
+ PI_UNREF(exec_ctx, pss->po.pi, "pss_destroy");
1856
2001
  }
1857
2002
 
1858
2003
  gpr_free(pss);
@@ -1952,7 +2097,6 @@ static const grpc_event_engine_vtable vtable = {
1952
2097
 
1953
2098
  .pollset_init = pollset_init,
1954
2099
  .pollset_shutdown = pollset_shutdown,
1955
- .pollset_reset = pollset_reset,
1956
2100
  .pollset_destroy = pollset_destroy,
1957
2101
  .pollset_work = pollset_work,
1958
2102
  .pollset_kick = pollset_kick,