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
@@ -37,21 +37,23 @@
37
37
  #include <sys/socket.h>
38
38
  #include <unistd.h>
39
39
 
40
+ #include "src/core/lib/iomgr/error.h"
41
+
40
42
  /* a wrapper for accept or accept4 */
41
43
  int grpc_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
42
44
  int nonblock, int cloexec);
43
45
 
44
46
  /* set a socket to non blocking mode */
45
- int grpc_set_socket_nonblocking(int fd, int non_blocking);
47
+ grpc_error *grpc_set_socket_nonblocking(int fd, int non_blocking);
46
48
 
47
49
  /* set a socket to close on exec */
48
- int grpc_set_socket_cloexec(int fd, int close_on_exec);
50
+ grpc_error *grpc_set_socket_cloexec(int fd, int close_on_exec);
49
51
 
50
52
  /* set a socket to reuse old addresses */
51
- int grpc_set_socket_reuse_addr(int fd, int reuse);
53
+ grpc_error *grpc_set_socket_reuse_addr(int fd, int reuse);
52
54
 
53
55
  /* disable nagle */
54
- int grpc_set_socket_low_latency(int fd, int low_latency);
56
+ grpc_error *grpc_set_socket_low_latency(int fd, int low_latency);
55
57
 
56
58
  /* Returns true if this system can create AF_INET6 sockets bound to ::1.
57
59
  The value is probed once, and cached for the life of the process.
@@ -64,19 +66,22 @@ int grpc_set_socket_low_latency(int fd, int low_latency);
64
66
  int grpc_ipv6_loopback_available(void);
65
67
 
66
68
  /* Tries to set SO_NOSIGPIPE if available on this platform.
67
- Returns 1 on success, 0 on failure.
68
69
  If SO_NO_SIGPIPE is not available, returns 1. */
69
- int grpc_set_socket_no_sigpipe_if_possible(int fd);
70
+ grpc_error *grpc_set_socket_no_sigpipe_if_possible(int fd);
70
71
 
71
72
  /* Tries to set IP_PKTINFO if available on this platform.
72
- Returns 1 on success, 0 on failure.
73
73
  If IP_PKTINFO is not available, returns 1. */
74
- int grpc_set_socket_ip_pktinfo_if_possible(int fd);
74
+ grpc_error *grpc_set_socket_ip_pktinfo_if_possible(int fd);
75
75
 
76
76
  /* Tries to set IPV6_RECVPKTINFO if available on this platform.
77
- Returns 1 on success, 0 on failure.
78
77
  If IPV6_RECVPKTINFO is not available, returns 1. */
79
- int grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd);
78
+ grpc_error *grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd);
79
+
80
+ /* Tries to set the socket's send buffer to given size. */
81
+ grpc_error *grpc_set_socket_sndbuf(int fd, int buffer_size_bytes);
82
+
83
+ /* Tries to set the socket's receive buffer to given size. */
84
+ grpc_error *grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes);
80
85
 
81
86
  /* An enum to keep track of IPv4/IPv6 socket modes.
82
87
 
@@ -117,7 +122,9 @@ extern int grpc_forbid_dualstack_sockets_for_testing;
117
122
  IPv4, so that bind() or connect() see the correct family.
118
123
  Also, it's important to distinguish between DUALSTACK and IPV6 when
119
124
  listening on the [::] wildcard address. */
120
- int grpc_create_dualstack_socket(const struct sockaddr *addr, int type,
121
- int protocol, grpc_dualstack_mode *dsmode);
125
+ grpc_error *grpc_create_dualstack_socket(const struct sockaddr *addr, int type,
126
+ int protocol,
127
+ grpc_dualstack_mode *dsmode,
128
+ int *newfd);
122
129
 
123
130
  #endif /* GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H */
@@ -42,7 +42,7 @@
42
42
 
43
43
  #include <grpc/support/alloc.h>
44
44
  #include <grpc/support/log.h>
45
- #include <grpc/support/log_win32.h>
45
+ #include <grpc/support/log_windows.h>
46
46
  #include <grpc/support/string_util.h>
47
47
 
48
48
  #include "src/core/lib/iomgr/iocp_windows.h"
@@ -91,10 +91,69 @@ void grpc_winsocket_shutdown(grpc_winsocket *winsocket) {
91
91
  closesocket(winsocket->socket);
92
92
  }
93
93
 
94
- void grpc_winsocket_destroy(grpc_winsocket *winsocket) {
94
+ static void destroy(grpc_winsocket *winsocket) {
95
95
  grpc_iomgr_unregister_object(&winsocket->iomgr_object);
96
96
  gpr_mu_destroy(&winsocket->state_mu);
97
97
  gpr_free(winsocket);
98
98
  }
99
99
 
100
+ static bool check_destroyable(grpc_winsocket *winsocket) {
101
+ return winsocket->destroy_called == true &&
102
+ winsocket->write_info.closure == NULL &&
103
+ winsocket->read_info.closure == NULL;
104
+ }
105
+
106
+ void grpc_winsocket_destroy(grpc_winsocket *winsocket) {
107
+ gpr_mu_lock(&winsocket->state_mu);
108
+ GPR_ASSERT(!winsocket->destroy_called);
109
+ winsocket->destroy_called = true;
110
+ bool should_destroy = check_destroyable(winsocket);
111
+ gpr_mu_unlock(&winsocket->state_mu);
112
+ if (should_destroy) destroy(winsocket);
113
+ }
114
+
115
+ /* Calling notify_on_read or write means either of two things:
116
+ -) The IOCP already completed in the background, and we need to call
117
+ the callback now.
118
+ -) The IOCP hasn't completed yet, and we're queuing it for later. */
119
+ static void socket_notify_on_iocp(grpc_exec_ctx *exec_ctx,
120
+ grpc_winsocket *socket, grpc_closure *closure,
121
+ grpc_winsocket_callback_info *info) {
122
+ GPR_ASSERT(info->closure == NULL);
123
+ gpr_mu_lock(&socket->state_mu);
124
+ if (info->has_pending_iocp) {
125
+ info->has_pending_iocp = 0;
126
+ grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_NONE, NULL);
127
+ } else {
128
+ info->closure = closure;
129
+ }
130
+ gpr_mu_unlock(&socket->state_mu);
131
+ }
132
+
133
+ void grpc_socket_notify_on_write(grpc_exec_ctx *exec_ctx,
134
+ grpc_winsocket *socket,
135
+ grpc_closure *closure) {
136
+ socket_notify_on_iocp(exec_ctx, socket, closure, &socket->write_info);
137
+ }
138
+
139
+ void grpc_socket_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_winsocket *socket,
140
+ grpc_closure *closure) {
141
+ socket_notify_on_iocp(exec_ctx, socket, closure, &socket->read_info);
142
+ }
143
+
144
+ void grpc_socket_become_ready(grpc_exec_ctx *exec_ctx, grpc_winsocket *socket,
145
+ grpc_winsocket_callback_info *info) {
146
+ GPR_ASSERT(!info->has_pending_iocp);
147
+ gpr_mu_lock(&socket->state_mu);
148
+ if (info->closure) {
149
+ grpc_exec_ctx_sched(exec_ctx, info->closure, GRPC_ERROR_NONE, NULL);
150
+ info->closure = NULL;
151
+ } else {
152
+ info->has_pending_iocp = 1;
153
+ }
154
+ bool should_destroy = check_destroyable(socket);
155
+ gpr_mu_unlock(&socket->state_mu);
156
+ if (should_destroy) destroy(socket);
157
+ }
158
+
100
159
  #endif /* GPR_WINSOCK_SOCKET */
@@ -81,6 +81,7 @@ typedef struct grpc_winsocket_callback_info {
81
81
  is closer to what happens in posix world. */
82
82
  typedef struct grpc_winsocket {
83
83
  SOCKET socket;
84
+ bool destroy_called;
84
85
 
85
86
  grpc_winsocket_callback_info write_info;
86
87
  grpc_winsocket_callback_info read_info;
@@ -108,4 +109,16 @@ void grpc_winsocket_shutdown(grpc_winsocket *socket);
108
109
  /* Destroy a socket. Should only be called if there's no pending operation. */
109
110
  void grpc_winsocket_destroy(grpc_winsocket *socket);
110
111
 
112
+ void grpc_socket_notify_on_write(grpc_exec_ctx *exec_ctx,
113
+ grpc_winsocket *winsocket,
114
+ grpc_closure *closure);
115
+
116
+ void grpc_socket_notify_on_read(grpc_exec_ctx *exec_ctx,
117
+ grpc_winsocket *winsocket,
118
+ grpc_closure *closure);
119
+
120
+ void grpc_socket_become_ready(grpc_exec_ctx *exec_ctx,
121
+ grpc_winsocket *winsocket,
122
+ grpc_winsocket_callback_info *ci);
123
+
111
124
  #endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */
@@ -71,33 +71,39 @@ typedef struct {
71
71
  grpc_closure *closure;
72
72
  } async_connect;
73
73
 
74
- static int prepare_socket(const struct sockaddr *addr, int fd) {
75
- if (fd < 0) {
76
- goto error;
74
+ static grpc_error *prepare_socket(const struct sockaddr *addr, int fd) {
75
+ grpc_error *err = GRPC_ERROR_NONE;
76
+
77
+ GPR_ASSERT(fd >= 0);
78
+
79
+ err = grpc_set_socket_nonblocking(fd, 1);
80
+ if (err != GRPC_ERROR_NONE) goto error;
81
+ err = grpc_set_socket_cloexec(fd, 1);
82
+ if (err != GRPC_ERROR_NONE) goto error;
83
+ if (!grpc_is_unix_socket(addr)) {
84
+ err = grpc_set_socket_low_latency(fd, 1);
85
+ if (err != GRPC_ERROR_NONE) goto error;
77
86
  }
78
-
79
- if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
80
- (!grpc_is_unix_socket(addr) && !grpc_set_socket_low_latency(fd, 1)) ||
81
- !grpc_set_socket_no_sigpipe_if_possible(fd)) {
82
- gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
83
- strerror(errno));
84
- goto error;
85
- }
86
- return 1;
87
+ err = grpc_set_socket_no_sigpipe_if_possible(fd);
88
+ if (err != GRPC_ERROR_NONE) goto error;
89
+ goto done;
87
90
 
88
91
  error:
89
92
  if (fd >= 0) {
90
93
  close(fd);
91
94
  }
92
- return 0;
95
+ done:
96
+ return err;
93
97
  }
94
98
 
95
- static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, bool success) {
99
+ static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
96
100
  int done;
97
101
  async_connect *ac = acp;
98
102
  if (grpc_tcp_trace) {
99
- gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: success=%d", ac->addr_str,
100
- success);
103
+ const char *str = grpc_error_string(error);
104
+ gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str,
105
+ str);
106
+ grpc_error_free_string(str);
101
107
  }
102
108
  gpr_mu_lock(&ac->mu);
103
109
  if (ac->fd != NULL) {
@@ -112,7 +118,7 @@ static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, bool success) {
112
118
  }
113
119
  }
114
120
 
115
- static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, bool success) {
121
+ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
116
122
  async_connect *ac = acp;
117
123
  int so_error = 0;
118
124
  socklen_t so_error_size;
@@ -122,9 +128,13 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, bool success) {
122
128
  grpc_closure *closure = ac->closure;
123
129
  grpc_fd *fd;
124
130
 
131
+ GRPC_ERROR_REF(error);
132
+
125
133
  if (grpc_tcp_trace) {
126
- gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: success=%d",
127
- ac->addr_str, success);
134
+ const char *str = grpc_error_string(error);
135
+ gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: error=%s",
136
+ ac->addr_str, str);
137
+ grpc_error_free_string(str);
128
138
  }
129
139
 
130
140
  gpr_mu_lock(&ac->mu);
@@ -136,15 +146,14 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, bool success) {
136
146
  grpc_timer_cancel(exec_ctx, &ac->alarm);
137
147
 
138
148
  gpr_mu_lock(&ac->mu);
139
- if (success) {
149
+ if (error == GRPC_ERROR_NONE) {
140
150
  do {
141
151
  so_error_size = sizeof(so_error);
142
152
  err = getsockopt(grpc_fd_wrapped_fd(fd), SOL_SOCKET, SO_ERROR, &so_error,
143
153
  &so_error_size);
144
154
  } while (err < 0 && errno == EINTR);
145
155
  if (err < 0) {
146
- gpr_log(GPR_ERROR, "failed to connect to '%s': getsockopt(ERROR): %s",
147
- ac->addr_str, strerror(errno));
156
+ error = GRPC_OS_ERROR(errno, "getsockopt");
148
157
  goto finish;
149
158
  } else if (so_error != 0) {
150
159
  if (so_error == ENOBUFS) {
@@ -169,14 +178,12 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, bool success) {
169
178
  } else {
170
179
  switch (so_error) {
171
180
  case ECONNREFUSED:
172
- gpr_log(
173
- GPR_ERROR,
174
- "failed to connect to '%s': socket error: connection refused",
175
- ac->addr_str);
181
+ error = grpc_error_set_int(error, GRPC_ERROR_INT_ERRNO, errno);
182
+ error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
183
+ "Connection refused");
176
184
  break;
177
185
  default:
178
- gpr_log(GPR_ERROR, "failed to connect to '%s': socket error: %d",
179
- ac->addr_str, so_error);
186
+ error = GRPC_OS_ERROR(errno, "getsockopt(SO_ERROR)");
180
187
  break;
181
188
  }
182
189
  goto finish;
@@ -188,8 +195,8 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, bool success) {
188
195
  goto finish;
189
196
  }
190
197
  } else {
191
- gpr_log(GPR_ERROR, "failed to connect to '%s': timeout occurred",
192
- ac->addr_str);
198
+ error =
199
+ grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, "Timeout occurred");
193
200
  goto finish;
194
201
  }
195
202
 
@@ -203,12 +210,18 @@ finish:
203
210
  }
204
211
  done = (--ac->refs == 0);
205
212
  gpr_mu_unlock(&ac->mu);
213
+ if (error != GRPC_ERROR_NONE) {
214
+ error = grpc_error_set_str(error, GRPC_ERROR_STR_DESCRIPTION,
215
+ "Failed to connect to remote host");
216
+ error =
217
+ grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, ac->addr_str);
218
+ }
206
219
  if (done) {
207
220
  gpr_mu_destroy(&ac->mu);
208
221
  gpr_free(ac->addr_str);
209
222
  gpr_free(ac);
210
223
  }
211
- grpc_exec_ctx_enqueue(exec_ctx, closure, *ep != NULL, NULL);
224
+ grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
212
225
  }
213
226
 
214
227
  static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
@@ -225,6 +238,7 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
225
238
  grpc_fd *fdobj;
226
239
  char *name;
227
240
  char *addr_str;
241
+ grpc_error *error;
228
242
 
229
243
  *ep = NULL;
230
244
 
@@ -234,9 +248,10 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
234
248
  addr_len = sizeof(addr6_v4mapped);
235
249
  }
236
250
 
237
- fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
238
- if (fd < 0) {
239
- gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
251
+ error = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
252
+ if (error != GRPC_ERROR_NONE) {
253
+ grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
254
+ return;
240
255
  }
241
256
  if (dsmode == GRPC_DSMODE_IPV4) {
242
257
  /* If we got an AF_INET socket, map the address back to IPv4. */
@@ -244,8 +259,8 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
244
259
  addr = (struct sockaddr *)&addr4_copy;
245
260
  addr_len = sizeof(addr4_copy);
246
261
  }
247
- if (!prepare_socket(addr, fd)) {
248
- grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL);
262
+ if ((error = prepare_socket(addr, fd)) != GRPC_ERROR_NONE) {
263
+ grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
249
264
  return;
250
265
  }
251
266
 
@@ -261,14 +276,14 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
261
276
 
262
277
  if (err >= 0) {
263
278
  *ep = grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str);
264
- grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL);
279
+ grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_NONE, NULL);
265
280
  goto done;
266
281
  }
267
282
 
268
283
  if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
269
- gpr_log(GPR_ERROR, "connect error to '%s': %s", addr_str, strerror(errno));
270
284
  grpc_fd_orphan(exec_ctx, fdobj, NULL, NULL, "tcp_client_connect_error");
271
- grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL);
285
+ grpc_exec_ctx_sched(exec_ctx, closure, GRPC_OS_ERROR(errno, "connect"),
286
+ NULL);
272
287
  goto done;
273
288
  }
274
289
 
@@ -35,11 +35,11 @@
35
35
 
36
36
  #ifdef GPR_WINSOCK_SOCKET
37
37
 
38
- #include "src/core/lib/iomgr/sockaddr_win32.h"
38
+ #include "src/core/lib/iomgr/sockaddr_windows.h"
39
39
 
40
40
  #include <grpc/support/alloc.h>
41
41
  #include <grpc/support/log.h>
42
- #include <grpc/support/log_win32.h>
42
+ #include <grpc/support/log_windows.h>
43
43
  #include <grpc/support/slice_buffer.h>
44
44
  #include <grpc/support/useful.h>
45
45
 
@@ -75,23 +75,25 @@ static void async_connect_unlock_and_cleanup(async_connect *ac,
75
75
  if (socket != NULL) grpc_winsocket_destroy(socket);
76
76
  }
77
77
 
78
- static void on_alarm(grpc_exec_ctx *exec_ctx, void *acp, bool occured) {
78
+ static void on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
79
79
  async_connect *ac = acp;
80
80
  gpr_mu_lock(&ac->mu);
81
- if (ac->socket != NULL) {
82
- grpc_winsocket_shutdown(ac->socket);
81
+ grpc_winsocket *socket = ac->socket;
82
+ ac->socket = NULL;
83
+ if (socket != NULL) {
84
+ grpc_winsocket_shutdown(socket);
83
85
  }
84
- async_connect_unlock_and_cleanup(ac, ac->socket);
86
+ async_connect_unlock_and_cleanup(ac, socket);
85
87
  }
86
88
 
87
- static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, bool from_iocp) {
89
+ static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
88
90
  async_connect *ac = acp;
89
- SOCKET sock = ac->socket->socket;
90
91
  grpc_endpoint **ep = ac->endpoint;
91
92
  GPR_ASSERT(*ep == NULL);
92
- grpc_winsocket_callback_info *info = &ac->socket->write_info;
93
93
  grpc_closure *on_done = ac->on_done;
94
94
 
95
+ GRPC_ERROR_REF(error);
96
+
95
97
  gpr_mu_lock(&ac->mu);
96
98
  grpc_winsocket *socket = ac->socket;
97
99
  ac->socket = NULL;
@@ -101,17 +103,15 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, bool from_iocp) {
101
103
 
102
104
  gpr_mu_lock(&ac->mu);
103
105
 
104
- if (from_iocp && socket != NULL) {
106
+ if (error == GRPC_ERROR_NONE && socket != NULL) {
105
107
  DWORD transfered_bytes = 0;
106
108
  DWORD flags;
107
- BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
108
- &transfered_bytes, FALSE, &flags);
109
+ BOOL wsa_success =
110
+ WSAGetOverlappedResult(socket->socket, &socket->write_info.overlapped,
111
+ &transfered_bytes, FALSE, &flags);
109
112
  GPR_ASSERT(transfered_bytes == 0);
110
113
  if (!wsa_success) {
111
- char *utf8_message = gpr_format_message(WSAGetLastError());
112
- gpr_log(GPR_ERROR, "on_connect error connecting to '%s': %s",
113
- ac->addr_name, utf8_message);
114
- gpr_free(utf8_message);
114
+ error = GRPC_WSA_ERROR(WSAGetLastError(), "ConnectEx");
115
115
  } else {
116
116
  *ep = grpc_tcp_create(socket, ac->addr_name);
117
117
  socket = NULL;
@@ -121,7 +121,7 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, bool from_iocp) {
121
121
  async_connect_unlock_and_cleanup(ac, socket);
122
122
  /* If the connection was aborted, the callback was already called when
123
123
  the deadline was met. */
124
- on_done->cb(exec_ctx, on_done->cb_arg, *ep != NULL);
124
+ grpc_exec_ctx_sched(exec_ctx, on_done, error, NULL);
125
125
  }
126
126
 
127
127
  /* Tries to issue one async connection, then schedules both an IOCP
@@ -141,10 +141,8 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
141
141
  LPFN_CONNECTEX ConnectEx;
142
142
  GUID guid = WSAID_CONNECTEX;
143
143
  DWORD ioctl_num_bytes;
144
- const char *message = NULL;
145
- char *utf8_message;
146
144
  grpc_winsocket_callback_info *info;
147
- int last_error;
145
+ grpc_error *error = GRPC_ERROR_NONE;
148
146
 
149
147
  *endpoint = NULL;
150
148
 
@@ -157,12 +155,12 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
157
155
  sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0,
158
156
  WSA_FLAG_OVERLAPPED);
159
157
  if (sock == INVALID_SOCKET) {
160
- message = "Unable to create socket: %s";
158
+ error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket");
161
159
  goto failure;
162
160
  }
163
161
 
164
- if (!grpc_tcp_prepare_socket(sock)) {
165
- message = "Unable to set socket options: %s";
162
+ error = grpc_tcp_prepare_socket(sock);
163
+ if (error != GRPC_ERROR_NONE) {
166
164
  goto failure;
167
165
  }
168
166
 
@@ -173,7 +171,8 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
173
171
  &ConnectEx, sizeof(ConnectEx), &ioctl_num_bytes, NULL, NULL);
174
172
 
175
173
  if (status != 0) {
176
- message = "Unable to retrieve ConnectEx pointer: %s";
174
+ error = GRPC_WSA_ERROR(WSAGetLastError(),
175
+ "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER)");
177
176
  goto failure;
178
177
  }
179
178
 
@@ -181,7 +180,7 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
181
180
 
182
181
  status = bind(sock, (struct sockaddr *)&local_address, sizeof(local_address));
183
182
  if (status != 0) {
184
- message = "Unable to bind socket: %s";
183
+ error = GRPC_WSA_ERROR(WSAGetLastError(), "bind");
185
184
  goto failure;
186
185
  }
187
186
 
@@ -193,9 +192,9 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
193
192
  /* It wouldn't be unusual to get a success immediately. But we'll still get
194
193
  an IOCP notification, so let's ignore it. */
195
194
  if (!success) {
196
- int error = WSAGetLastError();
197
- if (error != ERROR_IO_PENDING) {
198
- message = "ConnectEx failed: %s";
195
+ int last_error = WSAGetLastError();
196
+ if (last_error != ERROR_IO_PENDING) {
197
+ error = GRPC_WSA_ERROR(last_error, "ConnectEx");
199
198
  goto failure;
200
199
  }
201
200
  }
@@ -215,17 +214,18 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
215
214
  return;
216
215
 
217
216
  failure:
218
- last_error = WSAGetLastError();
219
- utf8_message = gpr_format_message(last_error);
220
- gpr_log(GPR_ERROR, message, utf8_message);
221
- gpr_log(GPR_ERROR, "last error = %d", last_error);
222
- gpr_free(utf8_message);
217
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
218
+ char *target_uri = grpc_sockaddr_to_uri(addr);
219
+ grpc_error *final_error = grpc_error_set_str(
220
+ GRPC_ERROR_CREATE_REFERENCING("Failed to connect", &error, 1),
221
+ GRPC_ERROR_STR_TARGET_ADDRESS, target_uri);
222
+ GRPC_ERROR_UNREF(error);
223
223
  if (socket != NULL) {
224
224
  grpc_winsocket_destroy(socket);
225
225
  } else if (sock != INVALID_SOCKET) {
226
226
  closesocket(sock);
227
227
  }
228
- grpc_exec_ctx_enqueue(exec_ctx, on_done, false, NULL);
228
+ grpc_exec_ctx_sched(exec_ctx, on_done, final_error, NULL);
229
229
  }
230
230
 
231
231
  #endif /* GPR_WINSOCK_SOCKET */