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
@@ -164,7 +164,8 @@ void grpc_init(void) {
164
164
  grpc_register_tracer("channel_stack_builder",
165
165
  &grpc_trace_channel_stack_builder);
166
166
  grpc_register_tracer("http1", &grpc_http1_trace);
167
- grpc_register_tracer("compression", &grpc_compress_filter_trace);
167
+ grpc_register_tracer("compression", &grpc_compression_trace);
168
+ grpc_register_tracer("op_failure", &grpc_trace_operation_failures);
168
169
  grpc_security_pre_init();
169
170
  grpc_iomgr_init();
170
171
  grpc_executor_init();
@@ -37,10 +37,10 @@
37
37
  #include <string.h>
38
38
 
39
39
  #include "src/core/lib/debug/trace.h"
40
- #include "src/core/lib/security/auth_filters.h"
41
- #include "src/core/lib/security/credentials.h"
42
- #include "src/core/lib/security/secure_endpoint.h"
43
- #include "src/core/lib/security/security_connector.h"
40
+ #include "src/core/lib/security/credentials/credentials.h"
41
+ #include "src/core/lib/security/transport/auth_filters.h"
42
+ #include "src/core/lib/security/transport/secure_endpoint.h"
43
+ #include "src/core/lib/security/transport/security_connector.h"
44
44
  #include "src/core/lib/surface/channel_init.h"
45
45
  #include "src/core/lib/tsi/transport_security_interface.h"
46
46
 
@@ -80,7 +80,8 @@ static void lame_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
80
80
  } else if (op->recv_trailing_metadata != NULL) {
81
81
  fill_metadata(elem, op->recv_trailing_metadata);
82
82
  }
83
- grpc_transport_stream_op_finish_with_failure(exec_ctx, op);
83
+ grpc_transport_stream_op_finish_with_failure(
84
+ exec_ctx, op, GRPC_ERROR_CREATE("lame client channel"));
84
85
  }
85
86
 
86
87
  static char *lame_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
@@ -91,23 +92,26 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx,
91
92
  grpc_channel_element *elem,
92
93
  grpc_transport_op *op) {
93
94
  if (op->on_connectivity_state_change) {
94
- GPR_ASSERT(*op->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE);
95
- *op->connectivity_state = GRPC_CHANNEL_FATAL_FAILURE;
96
- op->on_connectivity_state_change->cb(
97
- exec_ctx, op->on_connectivity_state_change->cb_arg, 1);
95
+ GPR_ASSERT(*op->connectivity_state != GRPC_CHANNEL_SHUTDOWN);
96
+ *op->connectivity_state = GRPC_CHANNEL_SHUTDOWN;
97
+ grpc_exec_ctx_sched(exec_ctx, op->on_connectivity_state_change,
98
+ GRPC_ERROR_NONE, NULL);
98
99
  }
99
100
  if (op->on_consumed != NULL) {
100
- op->on_consumed->cb(exec_ctx, op->on_consumed->cb_arg, 1);
101
+ grpc_exec_ctx_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE, NULL);
101
102
  }
102
103
  if (op->send_ping != NULL) {
103
- op->send_ping->cb(exec_ctx, op->send_ping->cb_arg, 0);
104
+ grpc_exec_ctx_sched(exec_ctx, op->send_ping,
105
+ GRPC_ERROR_CREATE("lame client channel"), NULL);
104
106
  }
107
+ GRPC_ERROR_UNREF(op->disconnect_with_error);
105
108
  }
106
109
 
107
110
  static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
108
111
  grpc_call_element_args *args) {}
109
112
 
110
113
  static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
114
+ const grpc_call_stats *stats,
111
115
  void *and_free_memory) {
112
116
  gpr_free(and_free_memory);
113
117
  }
@@ -127,7 +131,7 @@ const grpc_channel_filter grpc_lame_filter = {
127
131
  lame_start_transport_op,
128
132
  sizeof(call_data),
129
133
  init_call_elem,
130
- grpc_call_stack_ignore_set_pollset,
134
+ grpc_call_stack_ignore_set_pollset_or_pollset_set,
131
135
  destroy_call_elem,
132
136
  sizeof(channel_data),
133
137
  init_channel_elem,
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  *
3
- * Copyright 2015, Google Inc.
3
+ * Copyright 2015-2016, Google Inc.
4
4
  * All rights reserved.
5
5
  *
6
6
  * Redistribution and use in source and binary forms, with or without
@@ -69,11 +69,6 @@ typedef struct call_data call_data;
69
69
  typedef struct channel_data channel_data;
70
70
  typedef struct registered_method registered_method;
71
71
 
72
- typedef struct {
73
- call_data *next;
74
- call_data *prev;
75
- } call_link;
76
-
77
72
  typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type;
78
73
 
79
74
  typedef struct requested_call {
@@ -81,7 +76,6 @@ typedef struct requested_call {
81
76
  void *tag;
82
77
  grpc_server *server;
83
78
  grpc_completion_queue *cq_bound_to_call;
84
- grpc_completion_queue *cq_for_notification;
85
79
  grpc_call **call;
86
80
  grpc_cq_completion completion;
87
81
  grpc_metadata_array *initial_metadata;
@@ -108,6 +102,7 @@ struct channel_data {
108
102
  grpc_server *server;
109
103
  grpc_connectivity_state connectivity_state;
110
104
  grpc_channel *channel;
105
+ size_t cq_idx;
111
106
  /* linked list of all channels on a server */
112
107
  channel_data *next;
113
108
  channel_data *prev;
@@ -172,7 +167,7 @@ struct request_matcher {
172
167
  grpc_server *server;
173
168
  call_data *pending_head;
174
169
  call_data *pending_tail;
175
- gpr_stack_lockfree *requests;
170
+ gpr_stack_lockfree **requests_per_cq;
176
171
  };
177
172
 
178
173
  struct registered_method {
@@ -180,6 +175,7 @@ struct registered_method {
180
175
  char *host;
181
176
  grpc_server_register_method_payload_handling payload_handling;
182
177
  uint32_t flags;
178
+ /* one request matcher per method */
183
179
  request_matcher request_matcher;
184
180
  registered_method *next;
185
181
  };
@@ -195,6 +191,7 @@ struct grpc_server {
195
191
  grpc_completion_queue **cqs;
196
192
  grpc_pollset **pollsets;
197
193
  size_t cq_count;
194
+ bool started;
198
195
 
199
196
  /* The two following mutexes control access to server-state
200
197
  mu_global controls access to non-call-related state (e.g., channel state)
@@ -207,6 +204,7 @@ struct grpc_server {
207
204
  gpr_mu mu_call; /* mutex for call-specific state */
208
205
 
209
206
  registered_method *registered_methods;
207
+ /** one request matcher for unregistered methods */
210
208
  request_matcher unregistered_request_matcher;
211
209
  /** free list of available requested_calls indices */
212
210
  gpr_stack_lockfree *request_freelist;
@@ -232,9 +230,10 @@ struct grpc_server {
232
230
  #define SERVER_FROM_CALL_ELEM(elem) \
233
231
  (((channel_data *)(elem)->channel_data)->server)
234
232
 
235
- static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *calld, bool success);
233
+ static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *calld,
234
+ grpc_error *error);
236
235
  static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
237
- requested_call *rc);
236
+ size_t cq_idx, requested_call *rc, grpc_error *error);
238
237
  /* Before calling maybe_finish_shutdown, we must hold mu_global and not
239
238
  hold mu_call */
240
239
  static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server);
@@ -265,14 +264,14 @@ struct shutdown_cleanup_args {
265
264
  };
266
265
 
267
266
  static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
268
- bool iomgr_status_ignored) {
267
+ grpc_error *error) {
269
268
  struct shutdown_cleanup_args *a = arg;
270
269
  gpr_slice_unref(a->slice);
271
270
  gpr_free(a);
272
271
  }
273
272
 
274
273
  static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
275
- int send_goaway, int send_disconnect) {
274
+ int send_goaway, grpc_error *send_disconnect) {
276
275
  grpc_transport_op op;
277
276
  struct shutdown_cleanup_args *sc;
278
277
  grpc_channel_element *elem;
@@ -283,7 +282,7 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
283
282
  sc->slice = gpr_slice_from_copied_string("Server shutdown");
284
283
  op.goaway_message = &sc->slice;
285
284
  op.goaway_status = GRPC_STATUS_OK;
286
- op.disconnect = send_disconnect;
285
+ op.disconnect_with_error = send_disconnect;
287
286
  grpc_closure_init(&sc->closure, shutdown_cleanup, sc);
288
287
  op.on_consumed = &sc->closure;
289
288
 
@@ -294,14 +293,16 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
294
293
  static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx,
295
294
  channel_broadcaster *cb,
296
295
  int send_goaway,
297
- int force_disconnect) {
296
+ grpc_error *force_disconnect) {
298
297
  size_t i;
299
298
 
300
299
  for (i = 0; i < cb->num_channels; i++) {
301
- send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect);
300
+ send_shutdown(exec_ctx, cb->channels[i], send_goaway,
301
+ GRPC_ERROR_REF(force_disconnect));
302
302
  GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast");
303
303
  }
304
304
  gpr_free(cb->channels);
305
+ GRPC_ERROR_UNREF(force_disconnect);
305
306
  }
306
307
 
307
308
  /*
@@ -312,15 +313,23 @@ static void request_matcher_init(request_matcher *rm, size_t entries,
312
313
  grpc_server *server) {
313
314
  memset(rm, 0, sizeof(*rm));
314
315
  rm->server = server;
315
- rm->requests = gpr_stack_lockfree_create(entries);
316
+ rm->requests_per_cq =
317
+ gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count);
318
+ for (size_t i = 0; i < server->cq_count; i++) {
319
+ rm->requests_per_cq[i] = gpr_stack_lockfree_create(entries);
320
+ }
316
321
  }
317
322
 
318
323
  static void request_matcher_destroy(request_matcher *rm) {
319
- GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests) == -1);
320
- gpr_stack_lockfree_destroy(rm->requests);
324
+ for (size_t i = 0; i < rm->server->cq_count; i++) {
325
+ GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests_per_cq[i]) == -1);
326
+ gpr_stack_lockfree_destroy(rm->requests_per_cq[i]);
327
+ }
328
+ gpr_free(rm->requests_per_cq);
321
329
  }
322
330
 
323
- static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, bool success) {
331
+ static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem,
332
+ grpc_error *error) {
324
333
  grpc_call_destroy(grpc_call_from_top_element(elem));
325
334
  }
326
335
 
@@ -335,17 +344,24 @@ static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx,
335
344
  grpc_closure_init(
336
345
  &calld->kill_zombie_closure, kill_zombie,
337
346
  grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
338
- grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
347
+ grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure, GRPC_ERROR_NONE,
348
+ NULL);
339
349
  }
340
350
  }
341
351
 
342
352
  static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx,
343
353
  grpc_server *server,
344
- request_matcher *rm) {
354
+ request_matcher *rm,
355
+ grpc_error *error) {
345
356
  int request_id;
346
- while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) {
347
- fail_call(exec_ctx, server, &server->requested_calls[request_id]);
357
+ for (size_t i = 0; i < server->cq_count; i++) {
358
+ while ((request_id = gpr_stack_lockfree_pop(rm->requests_per_cq[i])) !=
359
+ -1) {
360
+ fail_call(exec_ctx, server, i, &server->requested_calls[request_id],
361
+ GRPC_ERROR_REF(error));
362
+ }
348
363
  }
364
+ GRPC_ERROR_UNREF(error);
349
365
  }
350
366
 
351
367
  /*
@@ -364,15 +380,19 @@ static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
364
380
  gpr_mu_destroy(&server->mu_call);
365
381
  while ((rm = server->registered_methods) != NULL) {
366
382
  server->registered_methods = rm->next;
367
- request_matcher_destroy(&rm->request_matcher);
383
+ if (server->started) {
384
+ request_matcher_destroy(&rm->request_matcher);
385
+ }
368
386
  gpr_free(rm->method);
369
387
  gpr_free(rm->host);
370
388
  gpr_free(rm);
371
389
  }
390
+ if (server->started) {
391
+ request_matcher_destroy(&server->unregistered_request_matcher);
392
+ }
372
393
  for (i = 0; i < server->cq_count; i++) {
373
394
  GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server");
374
395
  }
375
- request_matcher_destroy(&server->unregistered_request_matcher);
376
396
  gpr_stack_lockfree_destroy(server->request_freelist);
377
397
  gpr_free(server->cqs);
378
398
  gpr_free(server->pollsets);
@@ -398,7 +418,7 @@ static void orphan_channel(channel_data *chand) {
398
418
  }
399
419
 
400
420
  static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd,
401
- bool success) {
421
+ grpc_error *error) {
402
422
  channel_data *chand = cd;
403
423
  grpc_server *server = chand->server;
404
424
  GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server");
@@ -453,11 +473,11 @@ static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
453
473
  }
454
474
 
455
475
  static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
456
- call_data *calld, requested_call *rc) {
476
+ call_data *calld, size_t cq_idx, requested_call *rc) {
457
477
  grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
458
478
  grpc_call *call = calld->call;
459
479
  *rc->call = call;
460
- calld->cq_new = rc->cq_for_notification;
480
+ calld->cq_new = server->cqs[cq_idx];
461
481
  GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
462
482
  switch (rc->type) {
463
483
  case BATCH_CALL:
@@ -487,46 +507,57 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
487
507
  grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
488
508
  channel_data *chand = elem->channel_data;
489
509
  server_ref(chand->server);
490
- grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, true, done_request_event, rc,
491
- &rc->completion);
510
+ grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, GRPC_ERROR_NONE,
511
+ done_request_event, rc, &rc->completion);
492
512
  }
493
513
 
494
- static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
495
- call_data *calld = arg;
514
+ static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg,
515
+ grpc_error *error) {
516
+ grpc_call_element *call_elem = arg;
517
+ call_data *calld = call_elem->call_data;
518
+ channel_data *chand = call_elem->channel_data;
496
519
  request_matcher *rm = calld->request_matcher;
497
520
  grpc_server *server = rm->server;
498
521
 
499
- if (!success || gpr_atm_acq_load(&server->shutdown_flag)) {
522
+ if (error != GRPC_ERROR_NONE || gpr_atm_acq_load(&server->shutdown_flag)) {
500
523
  gpr_mu_lock(&calld->mu_state);
501
524
  calld->state = ZOMBIED;
502
525
  gpr_mu_unlock(&calld->mu_state);
503
526
  grpc_closure_init(
504
527
  &calld->kill_zombie_closure, kill_zombie,
505
528
  grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
506
- grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
529
+ grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure, error, NULL);
507
530
  return;
508
531
  }
509
532
 
510
- int request_id = gpr_stack_lockfree_pop(rm->requests);
511
- if (request_id == -1) {
512
- gpr_mu_lock(&server->mu_call);
513
- gpr_mu_lock(&calld->mu_state);
514
- calld->state = PENDING;
515
- gpr_mu_unlock(&calld->mu_state);
516
- if (rm->pending_head == NULL) {
517
- rm->pending_tail = rm->pending_head = calld;
533
+ for (size_t i = 0; i < server->cq_count; i++) {
534
+ size_t cq_idx = (chand->cq_idx + i) % server->cq_count;
535
+ int request_id = gpr_stack_lockfree_pop(rm->requests_per_cq[cq_idx]);
536
+ if (request_id == -1) {
537
+ continue;
518
538
  } else {
519
- rm->pending_tail->pending_next = calld;
520
- rm->pending_tail = calld;
539
+ gpr_mu_lock(&calld->mu_state);
540
+ calld->state = ACTIVATED;
541
+ gpr_mu_unlock(&calld->mu_state);
542
+ publish_call(exec_ctx, server, calld, cq_idx,
543
+ &server->requested_calls[request_id]);
544
+ return; /* early out */
521
545
  }
522
- calld->pending_next = NULL;
523
- gpr_mu_unlock(&server->mu_call);
546
+ }
547
+
548
+ /* no cq to take the request found: queue it on the slow list */
549
+ gpr_mu_lock(&server->mu_call);
550
+ gpr_mu_lock(&calld->mu_state);
551
+ calld->state = PENDING;
552
+ gpr_mu_unlock(&calld->mu_state);
553
+ if (rm->pending_head == NULL) {
554
+ rm->pending_tail = rm->pending_head = calld;
524
555
  } else {
525
- gpr_mu_lock(&calld->mu_state);
526
- calld->state = ACTIVATED;
527
- gpr_mu_unlock(&calld->mu_state);
528
- publish_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
556
+ rm->pending_tail->pending_next = calld;
557
+ rm->pending_tail = calld;
529
558
  }
559
+ calld->pending_next = NULL;
560
+ gpr_mu_unlock(&server->mu_call);
530
561
  }
531
562
 
532
563
  static void finish_start_new_rpc(
@@ -540,7 +571,8 @@ static void finish_start_new_rpc(
540
571
  calld->state = ZOMBIED;
541
572
  gpr_mu_unlock(&calld->mu_state);
542
573
  grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
543
- grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
574
+ grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure, GRPC_ERROR_NONE,
575
+ NULL);
544
576
  return;
545
577
  }
546
578
 
@@ -548,14 +580,14 @@ static void finish_start_new_rpc(
548
580
 
549
581
  switch (payload_handling) {
550
582
  case GRPC_SRM_PAYLOAD_NONE:
551
- publish_new_rpc(exec_ctx, calld, true);
583
+ publish_new_rpc(exec_ctx, elem, GRPC_ERROR_NONE);
552
584
  break;
553
585
  case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: {
554
586
  grpc_op op;
555
587
  memset(&op, 0, sizeof(op));
556
588
  op.op = GRPC_OP_RECV_MESSAGE;
557
589
  op.data.recv_message = &calld->payload;
558
- grpc_closure_init(&calld->publish, publish_new_rpc, calld);
590
+ grpc_closure_init(&calld->publish, publish_new_rpc, elem);
559
591
  grpc_call_start_batch_and_execute(exec_ctx, calld->call, &op, 1,
560
592
  &calld->publish);
561
593
  break;
@@ -636,16 +668,21 @@ static int num_channels(grpc_server *server) {
636
668
  }
637
669
 
638
670
  static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx,
639
- grpc_server *server) {
640
- registered_method *rm;
641
- request_matcher_kill_requests(exec_ctx, server,
642
- &server->unregistered_request_matcher);
643
- request_matcher_zombify_all_pending_calls(
644
- exec_ctx, &server->unregistered_request_matcher);
645
- for (rm = server->registered_methods; rm; rm = rm->next) {
646
- request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher);
647
- request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
671
+ grpc_server *server, grpc_error *error) {
672
+ if (server->started) {
673
+ request_matcher_kill_requests(exec_ctx, server,
674
+ &server->unregistered_request_matcher,
675
+ GRPC_ERROR_REF(error));
676
+ request_matcher_zombify_all_pending_calls(
677
+ exec_ctx, &server->unregistered_request_matcher);
678
+ for (registered_method *rm = server->registered_methods; rm;
679
+ rm = rm->next) {
680
+ request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher,
681
+ GRPC_ERROR_REF(error));
682
+ request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
683
+ }
648
684
  }
685
+ GRPC_ERROR_UNREF(error);
649
686
  }
650
687
 
651
688
  static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
@@ -655,7 +692,8 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
655
692
  return;
656
693
  }
657
694
 
658
- kill_pending_work_locked(exec_ctx, server);
695
+ kill_pending_work_locked(exec_ctx, server,
696
+ GRPC_ERROR_CREATE("Server Shutdown"));
659
697
 
660
698
  if (server->root_channel_data.next != &server->root_channel_data ||
661
699
  server->listeners_destroyed < num_listeners(server)) {
@@ -676,7 +714,8 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
676
714
  for (i = 0; i < server->num_shutdown_tags; i++) {
677
715
  server_ref(server);
678
716
  grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq,
679
- server->shutdown_tags[i].tag, 1, done_shutdown_event, server,
717
+ server->shutdown_tags[i].tag, GRPC_ERROR_NONE,
718
+ done_shutdown_event, server,
680
719
  &server->shutdown_tags[i].completion);
681
720
  }
682
721
  }
@@ -699,11 +738,12 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
699
738
  }
700
739
 
701
740
  static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
702
- bool success) {
741
+ grpc_error *error) {
703
742
  grpc_call_element *elem = ptr;
704
743
  call_data *calld = elem->call_data;
705
744
  gpr_timespec op_deadline;
706
745
 
746
+ GRPC_ERROR_REF(error);
707
747
  grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
708
748
  op_deadline = calld->recv_initial_metadata->deadline;
709
749
  if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
@@ -712,11 +752,13 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
712
752
  if (calld->host && calld->path) {
713
753
  /* do nothing */
714
754
  } else {
715
- success = 0;
755
+ GRPC_ERROR_UNREF(error);
756
+ error =
757
+ GRPC_ERROR_CREATE_REFERENCING("Missing :authority or :path", &error, 1);
716
758
  }
717
759
 
718
- calld->on_done_recv_initial_metadata->cb(
719
- exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success);
760
+ grpc_exec_ctx_sched(exec_ctx, calld->on_done_recv_initial_metadata, error,
761
+ NULL);
720
762
  }
721
763
 
722
764
  static void server_mutate_op(grpc_call_element *elem,
@@ -741,10 +783,10 @@ static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
741
783
  }
742
784
 
743
785
  static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
744
- bool success) {
786
+ grpc_error *error) {
745
787
  grpc_call_element *elem = ptr;
746
788
  call_data *calld = elem->call_data;
747
- if (success) {
789
+ if (error == GRPC_ERROR_NONE) {
748
790
  start_new_rpc(exec_ctx, elem);
749
791
  } else {
750
792
  gpr_mu_lock(&calld->mu_state);
@@ -752,7 +794,8 @@ static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
752
794
  calld->state = ZOMBIED;
753
795
  gpr_mu_unlock(&calld->mu_state);
754
796
  grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
755
- grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
797
+ grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure,
798
+ GRPC_ERROR_NONE, NULL);
756
799
  } else if (calld->state == PENDING) {
757
800
  calld->state = ZOMBIED;
758
801
  gpr_mu_unlock(&calld->mu_state);
@@ -769,9 +812,9 @@ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
769
812
  const void *transport_server_data) {
770
813
  channel_data *chand = cd;
771
814
  /* create a call */
772
- grpc_call *call =
773
- grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data,
774
- NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
815
+ grpc_call *call = grpc_call_create(chand->channel, NULL, 0, NULL, NULL,
816
+ transport_server_data, NULL, 0,
817
+ gpr_inf_future(GPR_CLOCK_MONOTONIC));
775
818
  grpc_call_element *elem =
776
819
  grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
777
820
  call_data *calld = elem->call_data;
@@ -785,10 +828,10 @@ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
785
828
  }
786
829
 
787
830
  static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd,
788
- bool iomgr_status_ignored) {
831
+ grpc_error *error) {
789
832
  channel_data *chand = cd;
790
833
  grpc_server *server = chand->server;
791
- if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
834
+ if (chand->connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
792
835
  grpc_transport_op op;
793
836
  memset(&op, 0, sizeof(op));
794
837
  op.on_connectivity_state_change = &chand->channel_connectivity_changed,
@@ -821,7 +864,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
821
864
  }
822
865
 
823
866
  static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
824
- void *ignored) {
867
+ const grpc_call_stats *stats, void *ignored) {
825
868
  channel_data *chand = elem->channel_data;
826
869
  call_data *calld = elem->call_data;
827
870
 
@@ -886,7 +929,7 @@ const grpc_channel_filter grpc_server_top_filter = {
886
929
  grpc_channel_next_op,
887
930
  sizeof(call_data),
888
931
  init_call_elem,
889
- grpc_call_stack_ignore_set_pollset,
932
+ grpc_call_stack_ignore_set_pollset_or_pollset_set,
890
933
  destroy_call_elem,
891
934
  sizeof(channel_data),
892
935
  init_channel_elem,
@@ -895,25 +938,46 @@ const grpc_channel_filter grpc_server_top_filter = {
895
938
  "server",
896
939
  };
897
940
 
898
- void grpc_server_register_completion_queue(grpc_server *server,
899
- grpc_completion_queue *cq,
900
- void *reserved) {
941
+ static void register_completion_queue(grpc_server *server,
942
+ grpc_completion_queue *cq,
943
+ bool is_non_listening, void *reserved) {
901
944
  size_t i, n;
902
- GRPC_API_TRACE(
903
- "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
904
- (server, cq, reserved));
905
945
  GPR_ASSERT(!reserved);
906
946
  for (i = 0; i < server->cq_count; i++) {
907
947
  if (server->cqs[i] == cq) return;
908
948
  }
909
- GRPC_CQ_INTERNAL_REF(cq, "server");
949
+
910
950
  grpc_cq_mark_server_cq(cq);
951
+
952
+ if (is_non_listening) {
953
+ grpc_cq_mark_non_listening_server_cq(cq);
954
+ }
955
+
956
+ GRPC_CQ_INTERNAL_REF(cq, "server");
911
957
  n = server->cq_count++;
912
958
  server->cqs = gpr_realloc(server->cqs,
913
959
  server->cq_count * sizeof(grpc_completion_queue *));
914
960
  server->cqs[n] = cq;
915
961
  }
916
962
 
963
+ void grpc_server_register_completion_queue(grpc_server *server,
964
+ grpc_completion_queue *cq,
965
+ void *reserved) {
966
+ GRPC_API_TRACE(
967
+ "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
968
+ (server, cq, reserved));
969
+ register_completion_queue(server, cq, false, reserved);
970
+ }
971
+
972
+ void grpc_server_register_non_listening_completion_queue(
973
+ grpc_server *server, grpc_completion_queue *cq, void *reserved) {
974
+ GRPC_API_TRACE(
975
+ "grpc_server_register_non_listening_completion_queue(server=%p, cq=%p, "
976
+ "reserved=%p)",
977
+ 3, (server, cq, reserved));
978
+ register_completion_queue(server, cq, true, reserved);
979
+ }
980
+
917
981
  grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
918
982
  size_t i;
919
983
 
@@ -940,8 +1004,6 @@ grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
940
1004
  for (i = 0; i < (size_t)server->max_requested_calls; i++) {
941
1005
  gpr_stack_lockfree_push(server->request_freelist, (int)i);
942
1006
  }
943
- request_matcher_init(&server->unregistered_request_matcher,
944
- server->max_requested_calls, server);
945
1007
  server->requested_calls = gpr_malloc(server->max_requested_calls *
946
1008
  sizeof(*server->requested_calls));
947
1009
 
@@ -985,8 +1047,6 @@ void *grpc_server_register_method(
985
1047
  }
986
1048
  m = gpr_malloc(sizeof(registered_method));
987
1049
  memset(m, 0, sizeof(*m));
988
- request_matcher_init(&m->request_matcher, server->max_requested_calls,
989
- server);
990
1050
  m->method = gpr_strdup(method);
991
1051
  m->host = gpr_strdup(host);
992
1052
  m->next = server->registered_methods;
@@ -1003,13 +1063,23 @@ void grpc_server_start(grpc_server *server) {
1003
1063
 
1004
1064
  GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
1005
1065
 
1066
+ server->started = true;
1067
+ size_t pollset_count = 0;
1006
1068
  server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
1007
1069
  for (i = 0; i < server->cq_count; i++) {
1008
- server->pollsets[i] = grpc_cq_pollset(server->cqs[i]);
1070
+ if (!grpc_cq_is_non_listening_server_cq(server->cqs[i])) {
1071
+ server->pollsets[pollset_count++] = grpc_cq_pollset(server->cqs[i]);
1072
+ }
1073
+ }
1074
+ request_matcher_init(&server->unregistered_request_matcher,
1075
+ server->max_requested_calls, server);
1076
+ for (registered_method *rm = server->registered_methods; rm; rm = rm->next) {
1077
+ request_matcher_init(&rm->request_matcher, server->max_requested_calls,
1078
+ server);
1009
1079
  }
1010
1080
 
1011
1081
  for (l = server->listeners; l; l = l->next) {
1012
- l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count);
1082
+ l->start(&exec_ctx, server, l->arg, server->pollsets, pollset_count);
1013
1083
  }
1014
1084
 
1015
1085
  grpc_exec_ctx_finish(&exec_ctx);
@@ -1017,8 +1087,8 @@ void grpc_server_start(grpc_server *server) {
1017
1087
 
1018
1088
  void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
1019
1089
  grpc_transport *transport,
1090
+ grpc_pollset *accepting_pollset,
1020
1091
  const grpc_channel_args *args) {
1021
- size_t i;
1022
1092
  size_t num_registered_methods;
1023
1093
  size_t alloc;
1024
1094
  registered_method *rm;
@@ -1033,12 +1103,6 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
1033
1103
  uint32_t max_probes = 0;
1034
1104
  grpc_transport_op op;
1035
1105
 
1036
- for (i = 0; i < s->cq_count; i++) {
1037
- memset(&op, 0, sizeof(op));
1038
- op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
1039
- grpc_transport_perform_op(exec_ctx, transport, &op);
1040
- }
1041
-
1042
1106
  channel =
1043
1107
  grpc_channel_create(exec_ctx, NULL, args, GRPC_SERVER_CHANNEL, transport);
1044
1108
  chand = (channel_data *)grpc_channel_stack_element(
@@ -1048,6 +1112,17 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
1048
1112
  server_ref(s);
1049
1113
  chand->channel = channel;
1050
1114
 
1115
+ size_t cq_idx;
1116
+ grpc_completion_queue *accepting_cq = grpc_cq_from_pollset(accepting_pollset);
1117
+ for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) {
1118
+ if (s->cqs[cq_idx] == accepting_cq) break;
1119
+ }
1120
+ if (cq_idx == s->cq_count) {
1121
+ /* completion queue not found: pick a random one to publish new calls to */
1122
+ cq_idx = (size_t)rand() % s->cq_count;
1123
+ }
1124
+ chand->cq_idx = cq_idx;
1125
+
1051
1126
  num_registered_methods = 0;
1052
1127
  for (rm = s->registered_methods; rm; rm = rm->next) {
1053
1128
  num_registered_methods++;
@@ -1092,7 +1167,9 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
1092
1167
  op.set_accept_stream_user_data = chand;
1093
1168
  op.on_connectivity_state_change = &chand->channel_connectivity_changed;
1094
1169
  op.connectivity_state = &chand->connectivity_state;
1095
- op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0;
1170
+ if (gpr_atm_acq_load(&s->shutdown_flag) != 0) {
1171
+ op.disconnect_with_error = GRPC_ERROR_CREATE("Server shutdown");
1172
+ }
1096
1173
  grpc_transport_perform_op(exec_ctx, transport, &op);
1097
1174
  }
1098
1175
 
@@ -1103,7 +1180,7 @@ void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg,
1103
1180
  }
1104
1181
 
1105
1182
  static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s,
1106
- bool success) {
1183
+ grpc_error *error) {
1107
1184
  grpc_server *server = s;
1108
1185
  gpr_mu_lock(&server->mu_global);
1109
1186
  server->listeners_destroyed++;
@@ -1125,8 +1202,8 @@ void grpc_server_shutdown_and_notify(grpc_server *server,
1125
1202
  gpr_mu_lock(&server->mu_global);
1126
1203
  grpc_cq_begin_op(cq, tag);
1127
1204
  if (server->shutdown_published) {
1128
- grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL,
1129
- gpr_malloc(sizeof(grpc_cq_completion)));
1205
+ grpc_cq_end_op(&exec_ctx, cq, tag, GRPC_ERROR_NONE, done_published_shutdown,
1206
+ NULL, gpr_malloc(sizeof(grpc_cq_completion)));
1130
1207
  gpr_mu_unlock(&server->mu_global);
1131
1208
  goto done;
1132
1209
  }
@@ -1149,7 +1226,8 @@ void grpc_server_shutdown_and_notify(grpc_server *server,
1149
1226
 
1150
1227
  /* collect all unregistered then registered calls */
1151
1228
  gpr_mu_lock(&server->mu_call);
1152
- kill_pending_work_locked(&exec_ctx, server);
1229
+ kill_pending_work_locked(&exec_ctx, server,
1230
+ GRPC_ERROR_CREATE("Server Shutdown"));
1153
1231
  gpr_mu_unlock(&server->mu_call);
1154
1232
 
1155
1233
  maybe_finish_shutdown(&exec_ctx, server);
@@ -1177,7 +1255,8 @@ void grpc_server_cancel_all_calls(grpc_server *server) {
1177
1255
  channel_broadcaster_init(server, &broadcaster);
1178
1256
  gpr_mu_unlock(&server->mu_global);
1179
1257
 
1180
- channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1);
1258
+ channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0,
1259
+ GRPC_ERROR_CREATE("Cancelling all calls"));
1181
1260
  grpc_exec_ctx_finish(&exec_ctx);
1182
1261
  }
1183
1262
 
@@ -1218,19 +1297,21 @@ void grpc_server_add_listener(
1218
1297
  }
1219
1298
 
1220
1299
  static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1221
- grpc_server *server,
1300
+ grpc_server *server, size_t cq_idx,
1222
1301
  requested_call *rc) {
1223
1302
  call_data *calld = NULL;
1224
1303
  request_matcher *rm = NULL;
1225
1304
  int request_id;
1226
1305
  if (gpr_atm_acq_load(&server->shutdown_flag)) {
1227
- fail_call(exec_ctx, server, rc);
1306
+ fail_call(exec_ctx, server, cq_idx, rc,
1307
+ GRPC_ERROR_CREATE("Server Shutdown"));
1228
1308
  return GRPC_CALL_OK;
1229
1309
  }
1230
1310
  request_id = gpr_stack_lockfree_pop(server->request_freelist);
1231
1311
  if (request_id == -1) {
1232
1312
  /* out of request ids: just fail this one */
1233
- fail_call(exec_ctx, server, rc);
1313
+ fail_call(exec_ctx, server, cq_idx, rc,
1314
+ GRPC_ERROR_CREATE("Server Shutdown"));
1234
1315
  return GRPC_CALL_OK;
1235
1316
  }
1236
1317
  switch (rc->type) {
@@ -1243,12 +1324,12 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1243
1324
  }
1244
1325
  server->requested_calls[request_id] = *rc;
1245
1326
  gpr_free(rc);
1246
- if (gpr_stack_lockfree_push(rm->requests, request_id)) {
1327
+ if (gpr_stack_lockfree_push(rm->requests_per_cq[cq_idx], request_id)) {
1247
1328
  /* this was the first queued request: we need to lock and start
1248
1329
  matching calls */
1249
1330
  gpr_mu_lock(&server->mu_call);
1250
1331
  while ((calld = rm->pending_head) != NULL) {
1251
- request_id = gpr_stack_lockfree_pop(rm->requests);
1332
+ request_id = gpr_stack_lockfree_pop(rm->requests_per_cq[cq_idx]);
1252
1333
  if (request_id == -1) break;
1253
1334
  rm->pending_head = calld->pending_next;
1254
1335
  gpr_mu_unlock(&server->mu_call);
@@ -1258,13 +1339,13 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1258
1339
  grpc_closure_init(
1259
1340
  &calld->kill_zombie_closure, kill_zombie,
1260
1341
  grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
1261
- grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true,
1262
- NULL);
1342
+ grpc_exec_ctx_sched(exec_ctx, &calld->kill_zombie_closure,
1343
+ GRPC_ERROR_NONE, NULL);
1263
1344
  } else {
1264
1345
  GPR_ASSERT(calld->state == PENDING);
1265
1346
  calld->state = ACTIVATED;
1266
1347
  gpr_mu_unlock(&calld->mu_state);
1267
- publish_call(exec_ctx, server, calld,
1348
+ publish_call(exec_ctx, server, calld, cq_idx,
1268
1349
  &server->requested_calls[request_id]);
1269
1350
  }
1270
1351
  gpr_mu_lock(&server->mu_call);
@@ -1288,7 +1369,13 @@ grpc_call_error grpc_server_request_call(
1288
1369
  "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)",
1289
1370
  7, (server, call, details, initial_metadata, cq_bound_to_call,
1290
1371
  cq_for_notification, tag));
1291
- if (!grpc_cq_is_server_cq(cq_for_notification)) {
1372
+ size_t cq_idx;
1373
+ for (cq_idx = 0; cq_idx < server->cq_count; cq_idx++) {
1374
+ if (server->cqs[cq_idx] == cq_for_notification) {
1375
+ break;
1376
+ }
1377
+ }
1378
+ if (cq_idx == server->cq_count) {
1292
1379
  gpr_free(rc);
1293
1380
  error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1294
1381
  goto done;
@@ -1299,11 +1386,10 @@ grpc_call_error grpc_server_request_call(
1299
1386
  rc->server = server;
1300
1387
  rc->tag = tag;
1301
1388
  rc->cq_bound_to_call = cq_bound_to_call;
1302
- rc->cq_for_notification = cq_for_notification;
1303
1389
  rc->call = call;
1304
1390
  rc->data.batch.details = details;
1305
1391
  rc->initial_metadata = initial_metadata;
1306
- error = queue_call_request(&exec_ctx, server, rc);
1392
+ error = queue_call_request(&exec_ctx, server, cq_idx, rc);
1307
1393
  done:
1308
1394
  grpc_exec_ctx_finish(&exec_ctx);
1309
1395
  return error;
@@ -1325,7 +1411,14 @@ grpc_call_error grpc_server_request_registered_call(
1325
1411
  "tag=%p)",
1326
1412
  9, (server, rmp, call, deadline, initial_metadata, optional_payload,
1327
1413
  cq_bound_to_call, cq_for_notification, tag));
1328
- if (!grpc_cq_is_server_cq(cq_for_notification)) {
1414
+
1415
+ size_t cq_idx;
1416
+ for (cq_idx = 0; cq_idx < server->cq_count; cq_idx++) {
1417
+ if (server->cqs[cq_idx] == cq_for_notification) {
1418
+ break;
1419
+ }
1420
+ }
1421
+ if (cq_idx == server->cq_count) {
1329
1422
  gpr_free(rc);
1330
1423
  error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1331
1424
  goto done;
@@ -1341,25 +1434,25 @@ grpc_call_error grpc_server_request_registered_call(
1341
1434
  rc->server = server;
1342
1435
  rc->tag = tag;
1343
1436
  rc->cq_bound_to_call = cq_bound_to_call;
1344
- rc->cq_for_notification = cq_for_notification;
1345
1437
  rc->call = call;
1346
1438
  rc->data.registered.registered_method = rm;
1347
1439
  rc->data.registered.deadline = deadline;
1348
1440
  rc->initial_metadata = initial_metadata;
1349
1441
  rc->data.registered.optional_payload = optional_payload;
1350
- error = queue_call_request(&exec_ctx, server, rc);
1442
+ error = queue_call_request(&exec_ctx, server, cq_idx, rc);
1351
1443
  done:
1352
1444
  grpc_exec_ctx_finish(&exec_ctx);
1353
1445
  return error;
1354
1446
  }
1355
1447
 
1356
1448
  static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1357
- requested_call *rc) {
1449
+ size_t cq_idx, requested_call *rc, grpc_error *error) {
1358
1450
  *rc->call = NULL;
1359
1451
  rc->initial_metadata->count = 0;
1452
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
1360
1453
 
1361
1454
  server_ref(server);
1362
- grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
1455
+ grpc_cq_end_op(exec_ctx, server->cqs[cq_idx], rc->tag, error,
1363
1456
  done_request_event, rc, &rc->completion);
1364
1457
  }
1365
1458