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
@@ -38,6 +38,7 @@
38
38
  #include "src/core/lib/iomgr/tcp_posix.h"
39
39
 
40
40
  #include <errno.h>
41
+ #include <stdbool.h>
41
42
  #include <stdlib.h>
42
43
  #include <string.h>
43
44
  #include <sys/socket.h>
@@ -74,7 +75,7 @@ typedef struct {
74
75
  grpc_endpoint base;
75
76
  grpc_fd *em_fd;
76
77
  int fd;
77
- int finished_edge;
78
+ bool finished_edge;
78
79
  msg_iovlen_type iov_size; /* Number of slices to allocate per read attempt */
79
80
  size_t slice_size;
80
81
  gpr_refcount refcount;
@@ -101,9 +102,9 @@ typedef struct {
101
102
  } grpc_tcp;
102
103
 
103
104
  static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */,
104
- bool success);
105
+ grpc_error *error);
105
106
  static void tcp_handle_write(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */,
106
- bool success);
107
+ grpc_error *error);
107
108
 
108
109
  static void tcp_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
109
110
  grpc_tcp *tcp = (grpc_tcp *)ep;
@@ -155,23 +156,26 @@ static void tcp_destroy(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
155
156
  TCP_UNREF(exec_ctx, tcp, "destroy");
156
157
  }
157
158
 
158
- static void call_read_cb(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, int success) {
159
+ static void call_read_cb(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp,
160
+ grpc_error *error) {
159
161
  grpc_closure *cb = tcp->read_cb;
160
162
 
161
- if (grpc_tcp_trace) {
163
+ if (false && grpc_tcp_trace) {
162
164
  size_t i;
163
- gpr_log(GPR_DEBUG, "read: success=%d", success);
165
+ const char *str = grpc_error_string(error);
166
+ gpr_log(GPR_DEBUG, "read: error=%s", str);
167
+ grpc_error_free_string(str);
164
168
  for (i = 0; i < tcp->incoming_buffer->count; i++) {
165
169
  char *dump = gpr_dump_slice(tcp->incoming_buffer->slices[i],
166
170
  GPR_DUMP_HEX | GPR_DUMP_ASCII);
167
- gpr_log(GPR_DEBUG, "READ %p: %s", tcp, dump);
171
+ gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump);
168
172
  gpr_free(dump);
169
173
  }
170
174
  }
171
175
 
172
176
  tcp->read_cb = NULL;
173
177
  tcp->incoming_buffer = NULL;
174
- cb->cb(exec_ctx, cb->cb_arg, success);
178
+ grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
175
179
  }
176
180
 
177
181
  #define MAX_READ_IOVEC 4
@@ -219,15 +223,14 @@ static void tcp_continue_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
219
223
  /* We've consumed the edge, request a new one */
220
224
  grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure);
221
225
  } else {
222
- /* TODO(klempner): Log interesting errors */
223
226
  gpr_slice_buffer_reset_and_unref(tcp->incoming_buffer);
224
- call_read_cb(exec_ctx, tcp, 0);
227
+ call_read_cb(exec_ctx, tcp, GRPC_OS_ERROR(errno, "recvmsg"));
225
228
  TCP_UNREF(exec_ctx, tcp, "read");
226
229
  }
227
230
  } else if (read_bytes == 0) {
228
231
  /* 0 read size ==> end of stream */
229
232
  gpr_slice_buffer_reset_and_unref(tcp->incoming_buffer);
230
- call_read_cb(exec_ctx, tcp, 0);
233
+ call_read_cb(exec_ctx, tcp, GRPC_ERROR_CREATE("EOF"));
231
234
  TCP_UNREF(exec_ctx, tcp, "read");
232
235
  } else {
233
236
  GPR_ASSERT((size_t)read_bytes <= tcp->incoming_buffer->length);
@@ -240,7 +243,7 @@ static void tcp_continue_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
240
243
  ++tcp->iov_size;
241
244
  }
242
245
  GPR_ASSERT((size_t)read_bytes == tcp->incoming_buffer->length);
243
- call_read_cb(exec_ctx, tcp, 1);
246
+ call_read_cb(exec_ctx, tcp, GRPC_ERROR_NONE);
244
247
  TCP_UNREF(exec_ctx, tcp, "read");
245
248
  }
246
249
 
@@ -248,13 +251,13 @@ static void tcp_continue_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
248
251
  }
249
252
 
250
253
  static void tcp_handle_read(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */,
251
- bool success) {
254
+ grpc_error *error) {
252
255
  grpc_tcp *tcp = (grpc_tcp *)arg;
253
256
  GPR_ASSERT(!tcp->finished_edge);
254
257
 
255
- if (!success) {
258
+ if (error != GRPC_ERROR_NONE) {
256
259
  gpr_slice_buffer_reset_and_unref(tcp->incoming_buffer);
257
- call_read_cb(exec_ctx, tcp, 0);
260
+ call_read_cb(exec_ctx, tcp, GRPC_ERROR_REF(error));
258
261
  TCP_UNREF(exec_ctx, tcp, "read");
259
262
  } else {
260
263
  tcp_continue_read(exec_ctx, tcp);
@@ -271,17 +274,16 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
271
274
  gpr_slice_buffer_swap(incoming_buffer, &tcp->last_read_buffer);
272
275
  TCP_REF(tcp, "read");
273
276
  if (tcp->finished_edge) {
274
- tcp->finished_edge = 0;
277
+ tcp->finished_edge = false;
275
278
  grpc_fd_notify_on_read(exec_ctx, tcp->em_fd, &tcp->read_closure);
276
279
  } else {
277
- grpc_exec_ctx_enqueue(exec_ctx, &tcp->read_closure, true, NULL);
280
+ grpc_exec_ctx_sched(exec_ctx, &tcp->read_closure, GRPC_ERROR_NONE, NULL);
278
281
  }
279
282
  }
280
283
 
281
- typedef enum { FLUSH_DONE, FLUSH_PENDING, FLUSH_ERROR } flush_result;
282
-
284
+ /* returns true if done, false if pending; if returning true, *error is set */
283
285
  #define MAX_WRITE_IOVEC 16
284
- static flush_result tcp_flush(grpc_tcp *tcp) {
286
+ static bool tcp_flush(grpc_tcp *tcp, grpc_error **error) {
285
287
  struct msghdr msg;
286
288
  struct iovec iov[MAX_WRITE_IOVEC];
287
289
  msg_iovlen_type iov_size;
@@ -331,10 +333,10 @@ static flush_result tcp_flush(grpc_tcp *tcp) {
331
333
  if (errno == EAGAIN) {
332
334
  tcp->outgoing_slice_idx = unwind_slice_idx;
333
335
  tcp->outgoing_byte_idx = unwind_byte_idx;
334
- return FLUSH_PENDING;
336
+ return false;
335
337
  } else {
336
- /* TODO(klempner): Log some of these */
337
- return FLUSH_ERROR;
338
+ *error = GRPC_OS_ERROR(errno, "sendmsg");
339
+ return true;
338
340
  }
339
341
  }
340
342
 
@@ -355,50 +357,50 @@ static flush_result tcp_flush(grpc_tcp *tcp) {
355
357
  }
356
358
 
357
359
  if (tcp->outgoing_slice_idx == tcp->outgoing_buffer->count) {
358
- return FLUSH_DONE;
360
+ *error = GRPC_ERROR_NONE;
361
+ return true;
359
362
  }
360
363
  };
361
364
  }
362
365
 
363
366
  static void tcp_handle_write(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */,
364
- bool success) {
367
+ grpc_error *error) {
365
368
  grpc_tcp *tcp = (grpc_tcp *)arg;
366
- flush_result status;
367
369
  grpc_closure *cb;
368
370
 
369
- if (!success) {
371
+ if (error != GRPC_ERROR_NONE) {
370
372
  cb = tcp->write_cb;
371
373
  tcp->write_cb = NULL;
372
- cb->cb(exec_ctx, cb->cb_arg, 0);
374
+ cb->cb(exec_ctx, cb->cb_arg, error);
373
375
  TCP_UNREF(exec_ctx, tcp, "write");
374
376
  return;
375
377
  }
376
378
 
377
- status = tcp_flush(tcp);
378
- if (status == FLUSH_PENDING) {
379
+ if (!tcp_flush(tcp, &error)) {
379
380
  grpc_fd_notify_on_write(exec_ctx, tcp->em_fd, &tcp->write_closure);
380
381
  } else {
381
382
  cb = tcp->write_cb;
382
383
  tcp->write_cb = NULL;
383
384
  GPR_TIMER_BEGIN("tcp_handle_write.cb", 0);
384
- cb->cb(exec_ctx, cb->cb_arg, status == FLUSH_DONE);
385
+ cb->cb(exec_ctx, cb->cb_arg, error);
385
386
  GPR_TIMER_END("tcp_handle_write.cb", 0);
386
387
  TCP_UNREF(exec_ctx, tcp, "write");
388
+ GRPC_ERROR_UNREF(error);
387
389
  }
388
390
  }
389
391
 
390
392
  static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
391
393
  gpr_slice_buffer *buf, grpc_closure *cb) {
392
394
  grpc_tcp *tcp = (grpc_tcp *)ep;
393
- flush_result status;
395
+ grpc_error *error = GRPC_ERROR_NONE;
394
396
 
395
- if (grpc_tcp_trace) {
397
+ if (false && grpc_tcp_trace) {
396
398
  size_t i;
397
399
 
398
400
  for (i = 0; i < buf->count; i++) {
399
401
  char *data =
400
402
  gpr_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII);
401
- gpr_log(GPR_DEBUG, "WRITE %p: %s", tcp, data);
403
+ gpr_log(GPR_DEBUG, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data);
402
404
  gpr_free(data);
403
405
  }
404
406
  }
@@ -408,20 +410,22 @@ static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
408
410
 
409
411
  if (buf->length == 0) {
410
412
  GPR_TIMER_END("tcp_write", 0);
411
- grpc_exec_ctx_enqueue(exec_ctx, cb, true, NULL);
413
+ grpc_exec_ctx_sched(exec_ctx, cb, grpc_fd_is_shutdown(tcp->em_fd)
414
+ ? GRPC_ERROR_CREATE("EOF")
415
+ : GRPC_ERROR_NONE,
416
+ NULL);
412
417
  return;
413
418
  }
414
419
  tcp->outgoing_buffer = buf;
415
420
  tcp->outgoing_slice_idx = 0;
416
421
  tcp->outgoing_byte_idx = 0;
417
422
 
418
- status = tcp_flush(tcp);
419
- if (status == FLUSH_PENDING) {
423
+ if (!tcp_flush(tcp, &error)) {
420
424
  TCP_REF(tcp, "write");
421
425
  tcp->write_cb = cb;
422
426
  grpc_fd_notify_on_write(exec_ctx, tcp->em_fd, &tcp->write_closure);
423
427
  } else {
424
- grpc_exec_ctx_enqueue(exec_ctx, cb, status == FLUSH_DONE, NULL);
428
+ grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
425
429
  }
426
430
 
427
431
  GPR_TIMER_END("tcp_write", 0);
@@ -461,7 +465,7 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size,
461
465
  tcp->incoming_buffer = NULL;
462
466
  tcp->slice_size = slice_size;
463
467
  tcp->iov_size = 1;
464
- tcp->finished_edge = 1;
468
+ tcp->finished_edge = true;
465
469
  /* paired with unref in grpc_tcp_destroy */
466
470
  gpr_ref_init(&tcp->refcount, 1);
467
471
  tcp->em_fd = em_fd;
@@ -52,12 +52,14 @@ typedef struct grpc_tcp_server_acceptor {
52
52
  /* Called for newly connected TCP connections. */
53
53
  typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg,
54
54
  grpc_endpoint *ep,
55
+ grpc_pollset *accepting_pollset,
55
56
  grpc_tcp_server_acceptor *acceptor);
56
57
 
57
58
  /* Create a server, initially not bound to any ports. The caller owns one ref.
58
59
  If shutdown_complete is not NULL, it will be used by
59
60
  grpc_tcp_server_unref() when the ref count reaches zero. */
60
- grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete);
61
+ grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,
62
+ grpc_tcp_server **server);
61
63
 
62
64
  /* Start listening to bound ports */
63
65
  void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server,
@@ -73,8 +75,8 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server,
73
75
  but not dualstack sockets. */
74
76
  /* TODO(ctiller): deprecate this, and make grpc_tcp_server_add_ports to handle
75
77
  all of the multiple socket port matching logic in one place */
76
- int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
77
- size_t addr_len);
78
+ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
79
+ size_t addr_len, int *out_port);
78
80
 
79
81
  /* Number of fds at the given port_index, or 0 if port_index is out of
80
82
  bounds. */
@@ -59,6 +59,8 @@
59
59
  #include <grpc/support/string_util.h>
60
60
  #include <grpc/support/sync.h>
61
61
  #include <grpc/support/time.h>
62
+ #include <grpc/support/useful.h>
63
+
62
64
  #include "src/core/lib/iomgr/resolve_address.h"
63
65
  #include "src/core/lib/iomgr/sockaddr_utils.h"
64
66
  #include "src/core/lib/iomgr/socket_utils_posix.h"
@@ -128,9 +130,13 @@ struct grpc_tcp_server {
128
130
  grpc_pollset **pollsets;
129
131
  /* number of pollsets in the pollsets array */
130
132
  size_t pollset_count;
133
+
134
+ /* next pollset to assign a channel to */
135
+ size_t next_pollset_to_assign;
131
136
  };
132
137
 
133
- grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
138
+ grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,
139
+ grpc_tcp_server **server) {
134
140
  grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
135
141
  gpr_ref_init(&s->refs, 1);
136
142
  gpr_mu_init(&s->mu);
@@ -145,12 +151,14 @@ grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
145
151
  s->head = NULL;
146
152
  s->tail = NULL;
147
153
  s->nports = 0;
148
- return s;
154
+ s->next_pollset_to_assign = 0;
155
+ *server = s;
156
+ return GRPC_ERROR_NONE;
149
157
  }
150
158
 
151
159
  static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
152
160
  if (s->shutdown_complete != NULL) {
153
- grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, true, NULL);
161
+ grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
154
162
  }
155
163
 
156
164
  gpr_mu_destroy(&s->mu);
@@ -165,7 +173,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
165
173
  }
166
174
 
167
175
  static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server,
168
- bool success) {
176
+ grpc_error *error) {
169
177
  grpc_tcp_server *s = server;
170
178
  gpr_mu_lock(&s->mu);
171
179
  s->destroyed_ports++;
@@ -259,64 +267,75 @@ static int get_max_accept_queue_size(void) {
259
267
  }
260
268
 
261
269
  /* Prepare a recently-created socket for listening. */
262
- static int prepare_socket(int fd, const struct sockaddr *addr,
263
- size_t addr_len) {
270
+ static grpc_error *prepare_socket(int fd, const struct sockaddr *addr,
271
+ size_t addr_len, int *port) {
264
272
  struct sockaddr_storage sockname_temp;
265
273
  socklen_t sockname_len;
266
-
267
- if (fd < 0) {
268
- goto error;
269
- }
270
-
271
- if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1) ||
272
- (!grpc_is_unix_socket(addr) && (!grpc_set_socket_low_latency(fd, 1) ||
273
- !grpc_set_socket_reuse_addr(fd, 1))) ||
274
- !grpc_set_socket_no_sigpipe_if_possible(fd)) {
275
- gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
276
- strerror(errno));
277
- goto error;
274
+ grpc_error *err = GRPC_ERROR_NONE;
275
+
276
+ GPR_ASSERT(fd >= 0);
277
+
278
+ err = grpc_set_socket_nonblocking(fd, 1);
279
+ if (err != GRPC_ERROR_NONE) goto error;
280
+ err = grpc_set_socket_cloexec(fd, 1);
281
+ if (err != GRPC_ERROR_NONE) goto error;
282
+ if (!grpc_is_unix_socket(addr)) {
283
+ err = grpc_set_socket_low_latency(fd, 1);
284
+ if (err != GRPC_ERROR_NONE) goto error;
285
+ err = grpc_set_socket_reuse_addr(fd, 1);
286
+ if (err != GRPC_ERROR_NONE) goto error;
278
287
  }
288
+ err = grpc_set_socket_no_sigpipe_if_possible(fd);
289
+ if (err != GRPC_ERROR_NONE) goto error;
279
290
 
280
291
  GPR_ASSERT(addr_len < ~(socklen_t)0);
281
292
  if (bind(fd, addr, (socklen_t)addr_len) < 0) {
282
- char *addr_str;
283
- grpc_sockaddr_to_string(&addr_str, addr, 0);
284
- gpr_log(GPR_ERROR, "bind addr=%s: %s", addr_str, strerror(errno));
285
- gpr_free(addr_str);
293
+ err = GRPC_OS_ERROR(errno, "bind");
286
294
  goto error;
287
295
  }
288
296
 
289
297
  if (listen(fd, get_max_accept_queue_size()) < 0) {
290
- gpr_log(GPR_ERROR, "listen: %s", strerror(errno));
298
+ err = GRPC_OS_ERROR(errno, "listen");
291
299
  goto error;
292
300
  }
293
301
 
294
302
  sockname_len = sizeof(sockname_temp);
295
303
  if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) {
304
+ err = GRPC_OS_ERROR(errno, "getsockname");
296
305
  goto error;
297
306
  }
298
307
 
299
- return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
308
+ *port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
309
+ return GRPC_ERROR_NONE;
300
310
 
301
311
  error:
312
+ GPR_ASSERT(err != GRPC_ERROR_NONE);
302
313
  if (fd >= 0) {
303
314
  close(fd);
304
315
  }
305
- return -1;
316
+ grpc_error *ret = grpc_error_set_int(
317
+ GRPC_ERROR_CREATE_REFERENCING("Unable to configure socket", &err, 1),
318
+ GRPC_ERROR_INT_FD, fd);
319
+ GRPC_ERROR_UNREF(err);
320
+ return ret;
306
321
  }
307
322
 
308
323
  /* event manager callback when reads are ready */
309
- static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
324
+ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *err) {
310
325
  grpc_tcp_listener *sp = arg;
311
326
  grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index,
312
327
  sp->fd_index};
328
+ grpc_pollset *read_notifier_pollset = NULL;
313
329
  grpc_fd *fdobj;
314
- size_t i;
315
330
 
316
- if (!success) {
331
+ if (err != GRPC_ERROR_NONE) {
317
332
  goto error;
318
333
  }
319
334
 
335
+ read_notifier_pollset =
336
+ sp->server->pollsets[(sp->server->next_pollset_to_assign++) %
337
+ sp->server->pollset_count];
338
+
320
339
  /* loop until accept4 returns EAGAIN, and then re-arm notification */
321
340
  for (;;) {
322
341
  struct sockaddr_storage addr;
@@ -349,16 +368,18 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
349
368
  }
350
369
 
351
370
  fdobj = grpc_fd_create(fd, name);
352
- /* TODO(ctiller): revise this when we have server-side sharding
353
- of channels -- we certainly should not be automatically adding every
354
- incoming channel to every pollset owned by the server */
355
- for (i = 0; i < sp->server->pollset_count; i++) {
356
- grpc_pollset_add_fd(exec_ctx, sp->server->pollsets[i], fdobj);
371
+
372
+ if (read_notifier_pollset == NULL) {
373
+ gpr_log(GPR_ERROR, "Read notifier pollset is not set on the fd");
374
+ goto error;
357
375
  }
376
+
377
+ grpc_pollset_add_fd(exec_ctx, read_notifier_pollset, fdobj);
378
+
358
379
  sp->server->on_accept_cb(
359
380
  exec_ctx, sp->server->on_accept_cb_arg,
360
381
  grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str),
361
- &acceptor);
382
+ read_notifier_pollset, &acceptor);
362
383
 
363
384
  gpr_free(name);
364
385
  gpr_free(addr_str);
@@ -376,18 +397,19 @@ error:
376
397
  }
377
398
  }
378
399
 
379
- static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
380
- const struct sockaddr *addr,
381
- size_t addr_len,
382
- unsigned port_index,
383
- unsigned fd_index) {
400
+ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
401
+ const struct sockaddr *addr,
402
+ size_t addr_len, unsigned port_index,
403
+ unsigned fd_index,
404
+ grpc_tcp_listener **listener) {
384
405
  grpc_tcp_listener *sp = NULL;
385
- int port;
406
+ int port = -1;
386
407
  char *addr_str;
387
408
  char *name;
388
409
 
389
- port = prepare_socket(fd, addr, addr_len);
390
- if (port >= 0) {
410
+ grpc_error *err = prepare_socket(fd, addr, addr_len, &port);
411
+ if (err == GRPC_ERROR_NONE) {
412
+ GPR_ASSERT(port > 0);
391
413
  grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
392
414
  gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
393
415
  gpr_mu_lock(&s->mu);
@@ -417,11 +439,12 @@ static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
417
439
  gpr_free(name);
418
440
  }
419
441
 
420
- return sp;
442
+ *listener = sp;
443
+ return err;
421
444
  }
422
445
 
423
- int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
424
- size_t addr_len) {
446
+ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
447
+ size_t addr_len, int *out_port) {
425
448
  grpc_tcp_listener *sp;
426
449
  grpc_tcp_listener *sp2 = NULL;
427
450
  int fd;
@@ -436,6 +459,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
436
459
  int port;
437
460
  unsigned port_index = 0;
438
461
  unsigned fd_index = 0;
462
+ grpc_error *errs[2] = {GRPC_ERROR_NONE, GRPC_ERROR_NONE};
439
463
  if (s->tail != NULL) {
440
464
  port_index = s->tail->port_index + 1;
441
465
  }
@@ -474,33 +498,35 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
474
498
  /* Try listening on IPv6 first. */
475
499
  addr = (struct sockaddr *)&wild6;
476
500
  addr_len = sizeof(wild6);
477
- fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
478
- sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
479
- if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
480
- goto done;
481
- }
482
- if (sp != NULL) {
483
- ++fd_index;
484
- }
485
- /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
486
- if (port == 0 && sp != NULL) {
487
- grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
501
+ errs[0] = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
502
+ if (errs[0] == GRPC_ERROR_NONE) {
503
+ errs[0] = add_socket_to_server(s, fd, addr, addr_len, port_index,
504
+ fd_index, &sp);
505
+ if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
506
+ goto done;
507
+ }
508
+ if (sp != NULL) {
509
+ ++fd_index;
510
+ }
511
+ /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
512
+ if (port == 0 && sp != NULL) {
513
+ grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
514
+ }
488
515
  }
489
516
  addr = (struct sockaddr *)&wild4;
490
517
  addr_len = sizeof(wild4);
491
518
  }
492
519
 
493
- fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
494
- if (fd < 0) {
495
- gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
496
- } else {
520
+ errs[1] = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
521
+ if (errs[1] == GRPC_ERROR_NONE) {
497
522
  if (dsmode == GRPC_DSMODE_IPV4 &&
498
523
  grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
499
524
  addr = (struct sockaddr *)&addr4_copy;
500
525
  addr_len = sizeof(addr4_copy);
501
526
  }
502
527
  sp2 = sp;
503
- sp = add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index);
528
+ errs[1] =
529
+ add_socket_to_server(s, fd, addr, addr_len, port_index, fd_index, &sp);
504
530
  if (sp2 != NULL && sp != NULL) {
505
531
  sp2->sibling = sp;
506
532
  sp->is_sibling = 1;
@@ -510,9 +536,21 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
510
536
  done:
511
537
  gpr_free(allocated_addr);
512
538
  if (sp != NULL) {
513
- return sp->port;
539
+ *out_port = sp->port;
540
+ GRPC_ERROR_UNREF(errs[0]);
541
+ GRPC_ERROR_UNREF(errs[1]);
542
+ return GRPC_ERROR_NONE;
514
543
  } else {
515
- return -1;
544
+ *out_port = -1;
545
+ char *addr_str = grpc_sockaddr_to_uri(addr);
546
+ grpc_error *err = grpc_error_set_str(
547
+ GRPC_ERROR_CREATE_REFERENCING("Failed to add port to server", errs,
548
+ GPR_ARRAY_SIZE(errs)),
549
+ GRPC_ERROR_STR_TARGET_ADDRESS, addr_str);
550
+ GRPC_ERROR_UNREF(errs[0]);
551
+ GRPC_ERROR_UNREF(errs[1]);
552
+ gpr_free(addr_str);
553
+ return err;
516
554
  }
517
555
  }
518
556
 
@@ -581,7 +619,8 @@ grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
581
619
  void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
582
620
  grpc_closure *shutdown_starting) {
583
621
  gpr_mu_lock(&s->mu);
584
- grpc_closure_list_add(&s->shutdown_starting, shutdown_starting, 1);
622
+ grpc_closure_list_append(&s->shutdown_starting, shutdown_starting,
623
+ GRPC_ERROR_NONE);
585
624
  gpr_mu_unlock(&s->mu);
586
625
  }
587
626