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
@@ -41,7 +41,7 @@
41
41
 
42
42
  #include <grpc/support/alloc.h>
43
43
  #include <grpc/support/log.h>
44
- #include <grpc/support/log_win32.h>
44
+ #include <grpc/support/log_windows.h>
45
45
  #include <grpc/support/string_util.h>
46
46
  #include <grpc/support/sync.h>
47
47
  #include <grpc/support/time.h>
@@ -102,7 +102,8 @@ struct grpc_tcp_server {
102
102
 
103
103
  /* Public function. Allocates the proper data structures to hold a
104
104
  grpc_tcp_server. */
105
- grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
105
+ grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,
106
+ grpc_tcp_server **server) {
106
107
  grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
107
108
  gpr_ref_init(&s->refs, 1);
108
109
  gpr_mu_init(&s->mu);
@@ -114,12 +115,13 @@ grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
114
115
  s->shutdown_starting.head = NULL;
115
116
  s->shutdown_starting.tail = NULL;
116
117
  s->shutdown_complete = shutdown_complete;
117
- return s;
118
+ *server = s;
119
+ return GRPC_ERROR_NONE;
118
120
  }
119
121
 
120
122
  static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
121
123
  if (s->shutdown_complete != NULL) {
122
- grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, true, NULL);
124
+ grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
123
125
  }
124
126
 
125
127
  /* Now that the accepts have been aborted, we can destroy the sockets.
@@ -143,7 +145,8 @@ grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
143
145
  void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
144
146
  grpc_closure *shutdown_starting) {
145
147
  gpr_mu_lock(&s->mu);
146
- grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1);
148
+ grpc_closure_list_append(&s->shutdown_starting, shutdown_starting,
149
+ GRPC_ERROR_NONE);
147
150
  gpr_mu_unlock(&s->mu);
148
151
  }
149
152
 
@@ -187,51 +190,49 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
187
190
  }
188
191
 
189
192
  /* Prepare (bind) a recently-created socket for listening. */
190
- static int prepare_socket(SOCKET sock, const struct sockaddr *addr,
191
- size_t addr_len) {
193
+ static grpc_error *prepare_socket(SOCKET sock, const struct sockaddr *addr,
194
+ size_t addr_len, int *port) {
192
195
  struct sockaddr_storage sockname_temp;
193
196
  socklen_t sockname_len;
197
+ grpc_error *error = GRPC_ERROR_NONE;
194
198
 
195
- if (sock == INVALID_SOCKET) goto error;
196
-
197
- if (!grpc_tcp_prepare_socket(sock)) {
198
- char *utf8_message = gpr_format_message(WSAGetLastError());
199
- gpr_log(GPR_ERROR, "Unable to prepare socket: %s", utf8_message);
200
- gpr_free(utf8_message);
201
- goto error;
199
+ error = grpc_tcp_prepare_socket(sock);
200
+ if (error != GRPC_ERROR_NONE) {
201
+ goto failure;
202
202
  }
203
203
 
204
204
  if (bind(sock, addr, (int)addr_len) == SOCKET_ERROR) {
205
- char *addr_str;
206
- char *utf8_message = gpr_format_message(WSAGetLastError());
207
- grpc_sockaddr_to_string(&addr_str, addr, 0);
208
- gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, utf8_message);
209
- gpr_free(utf8_message);
210
- gpr_free(addr_str);
211
- goto error;
205
+ error = GRPC_WSA_ERROR(WSAGetLastError(), "bind");
206
+ goto failure;
212
207
  }
213
208
 
214
209
  if (listen(sock, SOMAXCONN) == SOCKET_ERROR) {
215
- char *utf8_message = gpr_format_message(WSAGetLastError());
216
- gpr_log(GPR_ERROR, "listen: %s", utf8_message);
217
- gpr_free(utf8_message);
218
- goto error;
210
+ error = GRPC_WSA_ERROR(WSAGetLastError(), "listen");
211
+ goto failure;
219
212
  }
220
213
 
221
214
  sockname_len = sizeof(sockname_temp);
222
215
  if (getsockname(sock, (struct sockaddr *)&sockname_temp, &sockname_len) ==
223
216
  SOCKET_ERROR) {
224
- char *utf8_message = gpr_format_message(WSAGetLastError());
225
- gpr_log(GPR_ERROR, "getsockname: %s", utf8_message);
226
- gpr_free(utf8_message);
227
- goto error;
217
+ error = GRPC_WSA_ERROR(WSAGetLastError(), "getsockname");
218
+ goto failure;
228
219
  }
229
220
 
230
- return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
221
+ *port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
222
+ return GRPC_ERROR_NONE;
231
223
 
232
- error:
224
+ failure:
225
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
226
+ char *tgtaddr = grpc_sockaddr_to_uri(addr);
227
+ grpc_error *final_error = grpc_error_set_int(
228
+ grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING(
229
+ "Failed to prepare server socket", &error, 1),
230
+ GRPC_ERROR_STR_TARGET_ADDRESS, tgtaddr),
231
+ GRPC_ERROR_INT_FD, (intptr_t)sock);
232
+ gpr_free(tgtaddr);
233
+ GRPC_ERROR_UNREF(error);
233
234
  if (sock != INVALID_SOCKET) closesocket(sock);
234
- return -1;
235
+ return error;
235
236
  }
236
237
 
237
238
  static void decrement_active_ports_and_notify(grpc_exec_ctx *exec_ctx,
@@ -251,26 +252,23 @@ static void decrement_active_ports_and_notify(grpc_exec_ctx *exec_ctx,
251
252
 
252
253
  /* In order to do an async accept, we need to create a socket first which
253
254
  will be the one assigned to the new incoming connection. */
254
- static void start_accept(grpc_exec_ctx *exec_ctx, grpc_tcp_listener *port) {
255
+ static grpc_error *start_accept(grpc_exec_ctx *exec_ctx,
256
+ grpc_tcp_listener *port) {
255
257
  SOCKET sock = INVALID_SOCKET;
256
- char *message;
257
- char *utf8_message;
258
258
  BOOL success;
259
259
  DWORD addrlen = sizeof(struct sockaddr_in6) + 16;
260
260
  DWORD bytes_received = 0;
261
+ grpc_error *error = GRPC_ERROR_NONE;
261
262
 
262
263
  sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0,
263
264
  WSA_FLAG_OVERLAPPED);
264
-
265
265
  if (sock == INVALID_SOCKET) {
266
- message = "Unable to create socket: %s";
266
+ error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket");
267
267
  goto failure;
268
268
  }
269
269
 
270
- if (!grpc_tcp_prepare_socket(sock)) {
271
- message = "Unable to prepare socket: %s";
272
- goto failure;
273
- }
270
+ error = grpc_tcp_prepare_socket(sock);
271
+ if (error != GRPC_ERROR_NONE) goto failure;
274
272
 
275
273
  /* Start the "accept" asynchronously. */
276
274
  success = port->AcceptEx(port->socket->socket, sock, port->addresses, 0,
@@ -280,9 +278,9 @@ static void start_accept(grpc_exec_ctx *exec_ctx, grpc_tcp_listener *port) {
280
278
  /* It is possible to get an accept immediately without delay. However, we
281
279
  will still get an IOCP notification for it. So let's just ignore it. */
282
280
  if (!success) {
283
- int error = WSAGetLastError();
284
- if (error != ERROR_IO_PENDING) {
285
- message = "AcceptEx failed: %s";
281
+ int last_error = WSAGetLastError();
282
+ if (last_error != ERROR_IO_PENDING) {
283
+ error = GRPC_WSA_ERROR(last_error, "AcceptEx");
286
284
  goto failure;
287
285
  }
288
286
  }
@@ -291,9 +289,10 @@ static void start_accept(grpc_exec_ctx *exec_ctx, grpc_tcp_listener *port) {
291
289
  immediately process an accept that happened in the meantime. */
292
290
  port->new_socket = sock;
293
291
  grpc_socket_notify_on_read(exec_ctx, port->socket, &port->on_accept);
294
- return;
292
+ return error;
295
293
 
296
294
  failure:
295
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
297
296
  if (port->shutting_down) {
298
297
  /* We are abandoning the listener port, take that into account to prevent
299
298
  occasional hangs on shutdown. The hang happens when sp->shutting_down
@@ -301,16 +300,15 @@ failure:
301
300
  but we fail there because the listening port has been closed in the
302
301
  meantime. */
303
302
  decrement_active_ports_and_notify(exec_ctx, port);
304
- return;
303
+ GRPC_ERROR_UNREF(error);
304
+ return GRPC_ERROR_NONE;
305
305
  }
306
- utf8_message = gpr_format_message(WSAGetLastError());
307
- gpr_log(GPR_ERROR, message, utf8_message);
308
- gpr_free(utf8_message);
309
306
  if (sock != INVALID_SOCKET) closesocket(sock);
307
+ return error;
310
308
  }
311
309
 
312
310
  /* Event manager callback when reads are ready. */
313
- static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, bool from_iocp) {
311
+ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
314
312
  grpc_tcp_listener *sp = arg;
315
313
  grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index, 0};
316
314
  SOCKET sock = sp->new_socket;
@@ -328,7 +326,10 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, bool from_iocp) {
328
326
  /* The general mechanism for shutting down is to queue abortion calls. While
329
327
  this is necessary in the read/write case, it's useless for the accept
330
328
  case. We only need to adjust the pending callback count */
331
- if (!from_iocp) {
329
+ if (error != GRPC_ERROR_NONE) {
330
+ const char *msg = grpc_error_string(error);
331
+ gpr_log(GPR_INFO, "Skipping on_accept due to error: %s", msg);
332
+ grpc_error_free_string(msg);
332
333
  return;
333
334
  }
334
335
 
@@ -379,28 +380,28 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, bool from_iocp) {
379
380
 
380
381
  /* The only time we should call our callback, is where we successfully
381
382
  managed to accept a connection, and created an endpoint. */
382
- if (ep)
383
- sp->server->on_accept_cb(exec_ctx, sp->server->on_accept_cb_arg, ep,
383
+ if (ep) {
384
+ sp->server->on_accept_cb(exec_ctx, sp->server->on_accept_cb_arg, ep, NULL,
384
385
  &acceptor);
386
+ }
385
387
  /* As we were notified from the IOCP of one and exactly one accept,
386
388
  the former socked we created has now either been destroy or assigned
387
389
  to the new connection. We need to create a new one for the next
388
390
  connection. */
389
- start_accept(exec_ctx, sp);
391
+ GPR_ASSERT(GRPC_LOG_IF_ERROR("start_accept", start_accept(exec_ctx, sp)));
390
392
  }
391
393
 
392
- static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
393
- const struct sockaddr *addr,
394
- size_t addr_len,
395
- unsigned port_index) {
394
+ static grpc_error *add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
395
+ const struct sockaddr *addr,
396
+ size_t addr_len, unsigned port_index,
397
+ grpc_tcp_listener **listener) {
396
398
  grpc_tcp_listener *sp = NULL;
397
- int port;
399
+ int port = -1;
398
400
  int status;
399
401
  GUID guid = WSAID_ACCEPTEX;
400
402
  DWORD ioctl_num_bytes;
401
403
  LPFN_ACCEPTEX AcceptEx;
402
-
403
- if (sock == INVALID_SOCKET) return NULL;
404
+ grpc_error *error = GRPC_ERROR_NONE;
404
405
 
405
406
  /* We need to grab the AcceptEx pointer for that port, as it may be
406
407
  interface-dependent. We'll cache it to avoid doing that again. */
@@ -416,44 +417,49 @@ static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
416
417
  return NULL;
417
418
  }
418
419
 
419
- port = prepare_socket(sock, addr, addr_len);
420
- if (port >= 0) {
421
- gpr_mu_lock(&s->mu);
422
- GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
423
- sp = gpr_malloc(sizeof(grpc_tcp_listener));
424
- sp->next = NULL;
425
- if (s->head == NULL) {
426
- s->head = sp;
427
- } else {
428
- s->tail->next = sp;
429
- }
430
- s->tail = sp;
431
- sp->server = s;
432
- sp->socket = grpc_winsocket_create(sock, "listener");
433
- sp->shutting_down = 0;
434
- sp->AcceptEx = AcceptEx;
435
- sp->new_socket = INVALID_SOCKET;
436
- sp->port = port;
437
- sp->port_index = port_index;
438
- grpc_closure_init(&sp->on_accept, on_accept, sp);
439
- GPR_ASSERT(sp->socket);
440
- gpr_mu_unlock(&s->mu);
420
+ error = prepare_socket(sock, addr, addr_len, &port);
421
+ if (error != GRPC_ERROR_NONE) {
422
+ return error;
423
+ }
424
+
425
+ GPR_ASSERT(port >= 0);
426
+ gpr_mu_lock(&s->mu);
427
+ GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
428
+ sp = gpr_malloc(sizeof(grpc_tcp_listener));
429
+ sp->next = NULL;
430
+ if (s->head == NULL) {
431
+ s->head = sp;
432
+ } else {
433
+ s->tail->next = sp;
441
434
  }
435
+ s->tail = sp;
436
+ sp->server = s;
437
+ sp->socket = grpc_winsocket_create(sock, "listener");
438
+ sp->shutting_down = 0;
439
+ sp->AcceptEx = AcceptEx;
440
+ sp->new_socket = INVALID_SOCKET;
441
+ sp->port = port;
442
+ sp->port_index = port_index;
443
+ grpc_closure_init(&sp->on_accept, on_accept, sp);
444
+ GPR_ASSERT(sp->socket);
445
+ gpr_mu_unlock(&s->mu);
446
+ *listener = sp;
442
447
 
443
- return sp;
448
+ return GRPC_ERROR_NONE;
444
449
  }
445
450
 
446
- int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
447
- size_t addr_len) {
448
- grpc_tcp_listener *sp;
451
+ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
452
+ size_t addr_len, int *port) {
453
+ grpc_tcp_listener *sp = NULL;
449
454
  SOCKET sock;
450
455
  struct sockaddr_in6 addr6_v4mapped;
451
456
  struct sockaddr_in6 wildcard;
452
457
  struct sockaddr *allocated_addr = NULL;
453
458
  struct sockaddr_storage sockname_temp;
454
459
  socklen_t sockname_len;
455
- int port;
456
460
  unsigned port_index = 0;
461
+ grpc_error *error = GRPC_ERROR_NONE;
462
+
457
463
  if (s->tail != NULL) {
458
464
  port_index = s->tail->port_index + 1;
459
465
  }
@@ -465,11 +471,11 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
465
471
  sockname_len = sizeof(sockname_temp);
466
472
  if (0 == getsockname(sp->socket->socket,
467
473
  (struct sockaddr *)&sockname_temp, &sockname_len)) {
468
- port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
469
- if (port > 0) {
474
+ *port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
475
+ if (*port > 0) {
470
476
  allocated_addr = gpr_malloc(addr_len);
471
477
  memcpy(allocated_addr, addr, addr_len);
472
- grpc_sockaddr_set_port(allocated_addr, port);
478
+ grpc_sockaddr_set_port(allocated_addr, *port);
473
479
  addr = allocated_addr;
474
480
  break;
475
481
  }
@@ -483,8 +489,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
483
489
  }
484
490
 
485
491
  /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
486
- if (grpc_sockaddr_is_wildcard(addr, &port)) {
487
- grpc_sockaddr_make_wildcard6(port, &wildcard);
492
+ if (grpc_sockaddr_is_wildcard(addr, port)) {
493
+ grpc_sockaddr_make_wildcard6(*port, &wildcard);
488
494
 
489
495
  addr = (struct sockaddr *)&wildcard;
490
496
  addr_len = sizeof(wildcard);
@@ -493,19 +499,26 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
493
499
  sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0,
494
500
  WSA_FLAG_OVERLAPPED);
495
501
  if (sock == INVALID_SOCKET) {
496
- char *utf8_message = gpr_format_message(WSAGetLastError());
497
- gpr_log(GPR_ERROR, "unable to create socket: %s", utf8_message);
498
- gpr_free(utf8_message);
502
+ error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket");
503
+ goto done;
499
504
  }
500
505
 
501
- sp = add_socket_to_server(s, sock, addr, addr_len, port_index);
506
+ error = add_socket_to_server(s, sock, addr, addr_len, port_index, &sp);
507
+
508
+ done:
502
509
  gpr_free(allocated_addr);
503
510
 
504
- if (sp) {
505
- return sp->port;
511
+ if (error != GRPC_ERROR_NONE) {
512
+ grpc_error *error_out = GRPC_ERROR_CREATE_REFERENCING(
513
+ "Failed to add port to server", &error, 1);
514
+ GRPC_ERROR_UNREF(error);
515
+ error = error_out;
516
+ *port = -1;
506
517
  } else {
507
- return -1;
518
+ GPR_ASSERT(sp != NULL);
519
+ *port = sp->port;
508
520
  }
521
+ return error;
509
522
  }
510
523
 
511
524
  void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
@@ -520,7 +533,7 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
520
533
  s->on_accept_cb = on_accept_cb;
521
534
  s->on_accept_cb_arg = on_accept_cb_arg;
522
535
  for (sp = s->head; sp; sp = sp->next) {
523
- start_accept(exec_ctx, sp);
536
+ GPR_ASSERT(GRPC_LOG_IF_ERROR("start_accept", start_accept(exec_ctx, sp)));
524
537
  s->active_ports++;
525
538
  }
526
539
  gpr_mu_unlock(&s->mu);
@@ -37,11 +37,11 @@
37
37
 
38
38
  #include <limits.h>
39
39
 
40
- #include "src/core/lib/iomgr/sockaddr_win32.h"
40
+ #include "src/core/lib/iomgr/sockaddr_windows.h"
41
41
 
42
42
  #include <grpc/support/alloc.h>
43
43
  #include <grpc/support/log.h>
44
- #include <grpc/support/log_win32.h>
44
+ #include <grpc/support/log_windows.h>
45
45
  #include <grpc/support/slice_buffer.h>
46
46
  #include <grpc/support/string_util.h>
47
47
  #include <grpc/support/useful.h>
@@ -61,27 +61,34 @@
61
61
  #define GRPC_FIONBIO FIONBIO
62
62
  #endif
63
63
 
64
- static int set_non_block(SOCKET sock) {
64
+ static grpc_error *set_non_block(SOCKET sock) {
65
65
  int status;
66
66
  uint32_t param = 1;
67
67
  DWORD ret;
68
68
  status = WSAIoctl(sock, GRPC_FIONBIO, &param, sizeof(param), NULL, 0, &ret,
69
69
  NULL, NULL);
70
- return status == 0;
70
+ return status == 0
71
+ ? GRPC_ERROR_NONE
72
+ : GRPC_WSA_ERROR(WSAGetLastError(), "WSAIoctl(GRPC_FIONBIO)");
71
73
  }
72
74
 
73
- static int set_dualstack(SOCKET sock) {
75
+ static grpc_error *set_dualstack(SOCKET sock) {
74
76
  int status;
75
77
  unsigned long param = 0;
76
78
  status = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&param,
77
79
  sizeof(param));
78
- return status == 0;
80
+ return status == 0
81
+ ? GRPC_ERROR_NONE
82
+ : GRPC_WSA_ERROR(WSAGetLastError(), "setsockopt(IPV6_V6ONLY)");
79
83
  }
80
84
 
81
- int grpc_tcp_prepare_socket(SOCKET sock) {
82
- if (!set_non_block(sock)) return 0;
83
- if (!set_dualstack(sock)) return 0;
84
- return 1;
85
+ grpc_error *grpc_tcp_prepare_socket(SOCKET sock) {
86
+ grpc_error *err;
87
+ err = set_non_block(sock);
88
+ if (err != GRPC_ERROR_NONE) return err;
89
+ err = set_dualstack(sock);
90
+ if (err != GRPC_ERROR_NONE) return err;
91
+ return GRPC_ERROR_NONE;
85
92
  }
86
93
 
87
94
  typedef struct grpc_tcp {
@@ -148,39 +155,35 @@ static void tcp_ref(grpc_tcp *tcp) { gpr_ref(&tcp->refcount); }
148
155
  #endif
149
156
 
150
157
  /* Asynchronous callback from the IOCP, or the background thread. */
151
- static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, bool success) {
158
+ static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) {
152
159
  grpc_tcp *tcp = tcpp;
153
160
  grpc_closure *cb = tcp->read_cb;
154
161
  grpc_winsocket *socket = tcp->socket;
155
162
  gpr_slice sub;
156
163
  grpc_winsocket_callback_info *info = &socket->read_info;
157
164
 
158
- if (success) {
165
+ GRPC_ERROR_REF(error);
166
+
167
+ if (error == GRPC_ERROR_NONE) {
159
168
  if (info->wsa_error != 0 && !tcp->shutting_down) {
160
- if (info->wsa_error != WSAECONNRESET) {
161
- char *utf8_message = gpr_format_message(info->wsa_error);
162
- gpr_log(GPR_ERROR, "ReadFile overlapped error: %s", utf8_message);
163
- gpr_free(utf8_message);
164
- }
165
- success = 0;
169
+ char *utf8_message = gpr_format_message(info->wsa_error);
170
+ error = GRPC_ERROR_CREATE(utf8_message);
171
+ gpr_free(utf8_message);
166
172
  gpr_slice_unref(tcp->read_slice);
167
173
  } else {
168
174
  if (info->bytes_transfered != 0 && !tcp->shutting_down) {
169
175
  sub = gpr_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered);
170
176
  gpr_slice_buffer_add(tcp->read_slices, sub);
171
- success = 1;
172
177
  } else {
173
178
  gpr_slice_unref(tcp->read_slice);
174
- success = 0;
179
+ error = GRPC_ERROR_CREATE("End of TCP stream");
175
180
  }
176
181
  }
177
182
  }
178
183
 
179
184
  tcp->read_cb = NULL;
180
185
  TCP_UNREF(tcp, "read");
181
- if (cb) {
182
- cb->cb(exec_ctx, cb->cb_arg, success);
183
- }
186
+ grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
184
187
  }
185
188
 
186
189
  static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
@@ -194,7 +197,8 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
194
197
  WSABUF buffer;
195
198
 
196
199
  if (tcp->shutting_down) {
197
- grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL);
200
+ grpc_exec_ctx_sched(exec_ctx, cb,
201
+ GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
198
202
  return;
199
203
  }
200
204
 
@@ -218,7 +222,7 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
218
222
  /* Did we get data immediately ? Yay. */
219
223
  if (info->wsa_error != WSAEWOULDBLOCK) {
220
224
  info->bytes_transfered = bytes_read;
221
- grpc_exec_ctx_enqueue(exec_ctx, &tcp->on_read, true, NULL);
225
+ grpc_exec_ctx_sched(exec_ctx, &tcp->on_read, GRPC_ERROR_NONE, NULL);
222
226
  return;
223
227
  }
224
228
 
@@ -231,7 +235,8 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
231
235
  int wsa_error = WSAGetLastError();
232
236
  if (wsa_error != WSA_IO_PENDING) {
233
237
  info->wsa_error = wsa_error;
234
- grpc_exec_ctx_enqueue(exec_ctx, &tcp->on_read, false, NULL);
238
+ grpc_exec_ctx_sched(exec_ctx, &tcp->on_read,
239
+ GRPC_WSA_ERROR(info->wsa_error, "WSARecv"), NULL);
235
240
  return;
236
241
  }
237
242
  }
@@ -240,32 +245,29 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
240
245
  }
241
246
 
242
247
  /* Asynchronous callback from the IOCP, or the background thread. */
243
- static void on_write(grpc_exec_ctx *exec_ctx, void *tcpp, bool success) {
248
+ static void on_write(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) {
244
249
  grpc_tcp *tcp = (grpc_tcp *)tcpp;
245
250
  grpc_winsocket *handle = tcp->socket;
246
251
  grpc_winsocket_callback_info *info = &handle->write_info;
247
252
  grpc_closure *cb;
248
253
 
254
+ GRPC_ERROR_REF(error);
255
+
249
256
  gpr_mu_lock(&tcp->mu);
250
257
  cb = tcp->write_cb;
251
258
  tcp->write_cb = NULL;
252
259
  gpr_mu_unlock(&tcp->mu);
253
260
 
254
- if (success) {
261
+ if (error == GRPC_ERROR_NONE) {
255
262
  if (info->wsa_error != 0) {
256
- if (info->wsa_error != WSAECONNRESET) {
257
- char *utf8_message = gpr_format_message(info->wsa_error);
258
- gpr_log(GPR_ERROR, "WSASend overlapped error: %s", utf8_message);
259
- gpr_free(utf8_message);
260
- }
261
- success = 0;
263
+ error = GRPC_WSA_ERROR(info->wsa_error, "WSASend");
262
264
  } else {
263
265
  GPR_ASSERT(info->bytes_transfered == tcp->write_slices->length);
264
266
  }
265
267
  }
266
268
 
267
269
  TCP_UNREF(tcp, "write");
268
- cb->cb(exec_ctx, cb->cb_arg, success);
270
+ grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
269
271
  }
270
272
 
271
273
  /* Initiates a write. */
@@ -283,7 +285,8 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
283
285
  size_t len;
284
286
 
285
287
  if (tcp->shutting_down) {
286
- grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL);
288
+ grpc_exec_ctx_sched(exec_ctx, cb,
289
+ GRPC_ERROR_CREATE("TCP socket is shutting down"), NULL);
287
290
  return;
288
291
  }
289
292
 
@@ -311,19 +314,10 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
311
314
  connection that has its send queue filled up. But if we don't, then we can
312
315
  avoid doing an async write operation at all. */
313
316
  if (info->wsa_error != WSAEWOULDBLOCK) {
314
- bool ok = false;
315
- if (status == 0) {
316
- ok = true;
317
- GPR_ASSERT(bytes_sent == tcp->write_slices->length);
318
- } else {
319
- if (info->wsa_error != WSAECONNRESET) {
320
- char *utf8_message = gpr_format_message(info->wsa_error);
321
- gpr_log(GPR_ERROR, "WSASend error: %s", utf8_message);
322
- gpr_free(utf8_message);
323
- }
324
- }
325
- if (allocated) gpr_free(allocated);
326
- grpc_exec_ctx_enqueue(exec_ctx, cb, ok, NULL);
317
+ grpc_error *error = status == 0
318
+ ? GRPC_ERROR_NONE
319
+ : GRPC_WSA_ERROR(info->wsa_error, "WSASend");
320
+ grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
327
321
  return;
328
322
  }
329
323
 
@@ -340,7 +334,8 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
340
334
  int wsa_error = WSAGetLastError();
341
335
  if (wsa_error != WSA_IO_PENDING) {
342
336
  TCP_UNREF(tcp, "write");
343
- grpc_exec_ctx_enqueue(exec_ctx, cb, false, NULL);
337
+ grpc_exec_ctx_sched(exec_ctx, cb, GRPC_WSA_ERROR(wsa_error, "WSASend"),
338
+ NULL);
344
339
  return;
345
340
  }
346
341
  }