grpc 0.11.0 → 0.12.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 (459) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +29456 -0
  3. data/Rakefile +13 -8
  4. data/etc/roots.pem +5114 -0
  5. data/include/grpc/byte_buffer.h +120 -0
  6. data/include/grpc/byte_buffer_reader.h +58 -0
  7. data/include/grpc/census.h +488 -0
  8. data/include/grpc/compression.h +106 -0
  9. data/include/grpc/grpc.h +732 -0
  10. data/include/grpc/grpc_security.h +374 -0
  11. data/include/grpc/grpc_zookeeper.h +59 -0
  12. data/include/grpc/status.h +163 -0
  13. data/include/grpc/support/alloc.h +72 -0
  14. data/include/grpc/support/atm.h +92 -0
  15. data/include/grpc/support/atm_gcc_atomic.h +72 -0
  16. data/include/grpc/support/atm_gcc_sync.h +87 -0
  17. data/include/grpc/support/atm_win32.h +125 -0
  18. data/include/grpc/support/avl.h +91 -0
  19. data/include/grpc/support/cmdline.h +101 -0
  20. data/include/grpc/support/cpu.h +57 -0
  21. data/include/grpc/support/histogram.h +76 -0
  22. data/include/grpc/support/host_port.h +64 -0
  23. data/include/grpc/support/log.h +108 -0
  24. data/include/grpc/support/log_win32.h +51 -0
  25. data/include/grpc/support/port_platform.h +356 -0
  26. data/include/grpc/support/slice.h +182 -0
  27. data/include/grpc/support/slice_buffer.h +102 -0
  28. data/include/grpc/support/string_util.h +61 -0
  29. data/include/grpc/support/subprocess.h +57 -0
  30. data/include/grpc/support/sync.h +315 -0
  31. data/include/grpc/support/sync_generic.h +55 -0
  32. data/include/grpc/support/sync_posix.h +47 -0
  33. data/include/grpc/support/sync_win32.h +49 -0
  34. data/include/grpc/support/thd.h +91 -0
  35. data/include/grpc/support/time.h +128 -0
  36. data/include/grpc/support/tls.h +77 -0
  37. data/include/grpc/support/tls_gcc.h +56 -0
  38. data/include/grpc/support/tls_msvc.h +56 -0
  39. data/include/grpc/support/tls_pthread.h +60 -0
  40. data/include/grpc/support/useful.h +75 -0
  41. data/src/core/census/aggregation.h +66 -0
  42. data/src/core/census/context.c +46 -0
  43. data/src/core/census/context.h +47 -0
  44. data/src/core/census/grpc_context.c +53 -0
  45. data/src/core/census/grpc_filter.c +184 -0
  46. data/src/core/census/grpc_filter.h +44 -0
  47. data/src/core/census/initialize.c +57 -0
  48. data/src/core/census/operation.c +63 -0
  49. data/src/core/census/rpc_metric_id.h +51 -0
  50. data/src/core/census/tracing.c +45 -0
  51. data/src/core/channel/channel_args.c +209 -0
  52. data/src/core/channel/channel_args.h +88 -0
  53. data/src/core/channel/channel_stack.c +262 -0
  54. data/src/core/channel/channel_stack.h +260 -0
  55. data/src/core/channel/client_channel.c +524 -0
  56. data/src/core/channel/client_channel.h +63 -0
  57. data/src/core/channel/client_uchannel.c +243 -0
  58. data/src/core/channel/client_uchannel.h +60 -0
  59. data/src/core/channel/compress_filter.c +297 -0
  60. data/src/core/channel/compress_filter.h +65 -0
  61. data/src/core/channel/connected_channel.c +167 -0
  62. data/src/core/channel/connected_channel.h +51 -0
  63. data/src/core/channel/context.h +49 -0
  64. data/src/core/channel/http_client_filter.c +248 -0
  65. data/src/core/channel/http_client_filter.h +44 -0
  66. data/src/core/channel/http_server_filter.c +233 -0
  67. data/src/core/channel/http_server_filter.h +42 -0
  68. data/src/core/channel/subchannel_call_holder.c +259 -0
  69. data/src/core/channel/subchannel_call_holder.h +98 -0
  70. data/src/core/client_config/client_config.c +72 -0
  71. data/src/core/client_config/client_config.h +53 -0
  72. data/src/core/client_config/connector.c +54 -0
  73. data/src/core/client_config/connector.h +95 -0
  74. data/src/core/client_config/default_initial_connect_string.c +39 -0
  75. data/src/core/client_config/initial_connect_string.c +53 -0
  76. data/src/core/client_config/initial_connect_string.h +50 -0
  77. data/src/core/client_config/lb_policies/pick_first.c +398 -0
  78. data/src/core/client_config/lb_policies/pick_first.h +43 -0
  79. data/src/core/client_config/lb_policies/round_robin.c +537 -0
  80. data/src/core/client_config/lb_policies/round_robin.h +46 -0
  81. data/src/core/client_config/lb_policy.c +134 -0
  82. data/src/core/client_config/lb_policy.h +143 -0
  83. data/src/core/client_config/lb_policy_factory.c +48 -0
  84. data/src/core/client_config/lb_policy_factory.h +73 -0
  85. data/src/core/client_config/lb_policy_registry.c +88 -0
  86. data/src/core/client_config/lb_policy_registry.h +54 -0
  87. data/src/core/client_config/resolver.c +82 -0
  88. data/src/core/client_config/resolver.h +94 -0
  89. data/src/core/client_config/resolver_factory.c +55 -0
  90. data/src/core/client_config/resolver_factory.h +82 -0
  91. data/src/core/client_config/resolver_registry.c +137 -0
  92. data/src/core/client_config/resolver_registry.h +65 -0
  93. data/src/core/client_config/resolvers/dns_resolver.c +257 -0
  94. data/src/core/client_config/resolvers/dns_resolver.h +42 -0
  95. data/src/core/client_config/resolvers/sockaddr_resolver.c +391 -0
  96. data/src/core/client_config/resolvers/sockaddr_resolver.h +50 -0
  97. data/src/core/client_config/subchannel.c +697 -0
  98. data/src/core/client_config/subchannel.h +165 -0
  99. data/src/core/client_config/subchannel_factory.c +49 -0
  100. data/src/core/client_config/subchannel_factory.h +66 -0
  101. data/src/core/client_config/uri_parser.c +242 -0
  102. data/src/core/client_config/uri_parser.h +51 -0
  103. data/src/core/compression/algorithm.c +166 -0
  104. data/src/core/compression/algorithm_metadata.h +53 -0
  105. data/src/core/compression/message_compress.c +198 -0
  106. data/src/core/compression/message_compress.h +52 -0
  107. data/src/core/debug/trace.c +136 -0
  108. data/src/core/debug/trace.h +43 -0
  109. data/src/core/httpcli/format_request.c +120 -0
  110. data/src/core/httpcli/format_request.h +45 -0
  111. data/src/core/httpcli/httpcli.c +286 -0
  112. data/src/core/httpcli/httpcli.h +162 -0
  113. data/src/core/httpcli/httpcli_security_connector.c +189 -0
  114. data/src/core/httpcli/parser.c +211 -0
  115. data/src/core/httpcli/parser.h +64 -0
  116. data/src/core/iomgr/closure.c +98 -0
  117. data/src/core/iomgr/closure.h +97 -0
  118. data/src/core/iomgr/endpoint.c +67 -0
  119. data/src/core/iomgr/endpoint.h +102 -0
  120. data/src/core/iomgr/endpoint_pair.h +47 -0
  121. data/src/core/iomgr/endpoint_pair_posix.c +82 -0
  122. data/src/core/iomgr/endpoint_pair_windows.c +97 -0
  123. data/src/core/iomgr/exec_ctx.c +72 -0
  124. data/src/core/iomgr/exec_ctx.h +78 -0
  125. data/src/core/iomgr/executor.c +143 -0
  126. data/src/core/iomgr/executor.h +53 -0
  127. data/src/core/iomgr/fd_posix.c +438 -0
  128. data/src/core/iomgr/fd_posix.h +189 -0
  129. data/src/core/iomgr/iocp_windows.c +206 -0
  130. data/src/core/iomgr/iocp_windows.h +56 -0
  131. data/src/core/iomgr/iomgr.c +156 -0
  132. data/src/core/iomgr/iomgr.h +43 -0
  133. data/src/core/iomgr/iomgr_internal.h +58 -0
  134. data/src/core/iomgr/iomgr_posix.c +52 -0
  135. data/src/core/iomgr/iomgr_posix.h +39 -0
  136. data/src/core/iomgr/iomgr_windows.c +73 -0
  137. data/src/core/iomgr/pollset.h +95 -0
  138. data/src/core/iomgr/pollset_multipoller_with_epoll.c +258 -0
  139. data/src/core/iomgr/pollset_multipoller_with_poll_posix.c +227 -0
  140. data/src/core/iomgr/pollset_posix.c +638 -0
  141. data/src/core/iomgr/pollset_posix.h +147 -0
  142. data/src/core/iomgr/pollset_set.h +67 -0
  143. data/src/core/iomgr/pollset_set_posix.c +182 -0
  144. data/src/core/iomgr/pollset_set_posix.h +61 -0
  145. data/src/core/iomgr/pollset_set_windows.c +60 -0
  146. data/src/core/iomgr/pollset_set_windows.h +39 -0
  147. data/src/core/iomgr/pollset_windows.c +248 -0
  148. data/src/core/iomgr/pollset_windows.h +79 -0
  149. data/src/core/iomgr/resolve_address.h +72 -0
  150. data/src/core/iomgr/resolve_address_posix.c +183 -0
  151. data/src/core/iomgr/resolve_address_windows.c +166 -0
  152. data/src/core/iomgr/sockaddr.h +47 -0
  153. data/src/core/iomgr/sockaddr_posix.h +44 -0
  154. data/src/core/iomgr/sockaddr_utils.c +234 -0
  155. data/src/core/iomgr/sockaddr_utils.h +89 -0
  156. data/src/core/iomgr/sockaddr_win32.h +46 -0
  157. data/src/core/iomgr/socket_utils_common_posix.c +208 -0
  158. data/src/core/iomgr/socket_utils_linux.c +51 -0
  159. data/src/core/iomgr/socket_utils_posix.c +70 -0
  160. data/src/core/iomgr/socket_utils_posix.h +113 -0
  161. data/src/core/iomgr/socket_windows.c +98 -0
  162. data/src/core/iomgr/socket_windows.h +111 -0
  163. data/src/core/iomgr/tcp_client.h +53 -0
  164. data/src/core/iomgr/tcp_client_posix.c +304 -0
  165. data/src/core/iomgr/tcp_client_windows.c +221 -0
  166. data/src/core/iomgr/tcp_posix.c +485 -0
  167. data/src/core/iomgr/tcp_posix.h +65 -0
  168. data/src/core/iomgr/tcp_server.h +83 -0
  169. data/src/core/iomgr/tcp_server_posix.c +562 -0
  170. data/src/core/iomgr/tcp_server_windows.c +509 -0
  171. data/src/core/iomgr/tcp_windows.c +406 -0
  172. data/src/core/iomgr/tcp_windows.h +57 -0
  173. data/src/core/iomgr/time_averaged_stats.c +77 -0
  174. data/src/core/iomgr/time_averaged_stats.h +88 -0
  175. data/src/core/iomgr/timer.c +345 -0
  176. data/src/core/iomgr/timer.h +89 -0
  177. data/src/core/iomgr/timer_heap.c +148 -0
  178. data/src/core/iomgr/timer_heap.h +57 -0
  179. data/src/core/iomgr/timer_internal.h +61 -0
  180. data/src/core/iomgr/udp_server.c +439 -0
  181. data/src/core/iomgr/udp_server.h +83 -0
  182. data/src/core/iomgr/wakeup_fd_eventfd.c +85 -0
  183. data/src/core/iomgr/wakeup_fd_nospecial.c +51 -0
  184. data/src/core/iomgr/wakeup_fd_pipe.c +97 -0
  185. data/src/core/iomgr/wakeup_fd_pipe.h +41 -0
  186. data/src/core/iomgr/wakeup_fd_posix.c +72 -0
  187. data/src/core/iomgr/wakeup_fd_posix.h +101 -0
  188. data/src/core/iomgr/workqueue.h +85 -0
  189. data/src/core/iomgr/workqueue_posix.c +143 -0
  190. data/src/core/iomgr/workqueue_posix.h +51 -0
  191. data/src/core/iomgr/workqueue_windows.c +40 -0
  192. data/src/core/iomgr/workqueue_windows.h +37 -0
  193. data/src/core/json/json.c +64 -0
  194. data/src/core/json/json.h +88 -0
  195. data/src/core/json/json_common.h +49 -0
  196. data/src/core/json/json_reader.c +660 -0
  197. data/src/core/json/json_reader.h +160 -0
  198. data/src/core/json/json_string.c +379 -0
  199. data/src/core/json/json_writer.c +260 -0
  200. data/src/core/json/json_writer.h +97 -0
  201. data/src/core/profiling/basic_timers.c +274 -0
  202. data/src/core/profiling/stap_timers.c +65 -0
  203. data/src/core/profiling/timers.h +119 -0
  204. data/src/core/security/auth_filters.h +42 -0
  205. data/src/core/security/base64.c +233 -0
  206. data/src/core/security/base64.h +52 -0
  207. data/src/core/security/client_auth_filter.c +337 -0
  208. data/src/core/security/credentials.c +1273 -0
  209. data/src/core/security/credentials.h +376 -0
  210. data/src/core/security/credentials_metadata.c +101 -0
  211. data/src/core/security/credentials_posix.c +61 -0
  212. data/src/core/security/credentials_win32.c +61 -0
  213. data/src/core/security/google_default_credentials.c +260 -0
  214. data/src/core/security/handshake.c +327 -0
  215. data/src/core/security/handshake.h +50 -0
  216. data/src/core/security/json_token.c +405 -0
  217. data/src/core/security/json_token.h +118 -0
  218. data/src/core/security/jwt_verifier.c +842 -0
  219. data/src/core/security/jwt_verifier.h +136 -0
  220. data/src/core/security/secure_endpoint.c +383 -0
  221. data/src/core/security/secure_endpoint.h +49 -0
  222. data/src/core/security/security_connector.c +756 -0
  223. data/src/core/security/security_connector.h +246 -0
  224. data/src/core/security/security_context.c +342 -0
  225. data/src/core/security/security_context.h +114 -0
  226. data/src/core/security/server_auth_filter.c +264 -0
  227. data/src/core/security/server_secure_chttp2.c +268 -0
  228. data/src/core/statistics/census_interface.h +76 -0
  229. data/src/core/statistics/census_rpc_stats.h +101 -0
  230. data/src/core/support/alloc.c +90 -0
  231. data/src/core/support/avl.c +288 -0
  232. data/src/core/support/block_annotate.h +48 -0
  233. data/src/core/support/cmdline.c +347 -0
  234. data/src/core/support/cpu_iphone.c +49 -0
  235. data/src/core/support/cpu_linux.c +78 -0
  236. data/src/core/support/cpu_posix.c +77 -0
  237. data/src/core/support/cpu_windows.c +47 -0
  238. data/src/core/support/env.h +60 -0
  239. data/src/core/support/env_linux.c +62 -0
  240. data/src/core/support/env_posix.c +57 -0
  241. data/src/core/support/env_win32.c +65 -0
  242. data/src/core/support/file.c +91 -0
  243. data/src/core/support/file.h +63 -0
  244. data/src/core/support/file_posix.c +85 -0
  245. data/src/core/support/file_win32.c +84 -0
  246. data/src/core/support/histogram.c +244 -0
  247. data/src/core/support/host_port.c +110 -0
  248. data/src/core/support/log.c +66 -0
  249. data/src/core/support/log_android.c +87 -0
  250. data/src/core/support/log_linux.c +105 -0
  251. data/src/core/support/log_posix.c +102 -0
  252. data/src/core/support/log_win32.c +125 -0
  253. data/src/core/support/murmur_hash.c +96 -0
  254. data/src/core/support/murmur_hash.h +44 -0
  255. data/src/core/support/slice.c +343 -0
  256. data/src/core/support/slice_buffer.c +282 -0
  257. data/src/core/support/stack_lockfree.c +175 -0
  258. data/src/core/support/stack_lockfree.h +53 -0
  259. data/src/core/support/string.c +296 -0
  260. data/src/core/support/string.h +121 -0
  261. data/src/core/support/string_posix.c +86 -0
  262. data/src/core/support/string_win32.c +109 -0
  263. data/src/core/support/string_win32.h +47 -0
  264. data/src/core/support/subprocess_posix.c +112 -0
  265. data/src/core/support/sync.c +122 -0
  266. data/src/core/support/sync_posix.c +104 -0
  267. data/src/core/support/sync_win32.c +128 -0
  268. data/src/core/support/thd.c +64 -0
  269. data/src/core/support/thd_internal.h +39 -0
  270. data/src/core/support/thd_posix.c +94 -0
  271. data/src/core/support/thd_win32.c +117 -0
  272. data/src/core/support/time.c +304 -0
  273. data/src/core/support/time_posix.c +161 -0
  274. data/src/core/support/time_precise.c +89 -0
  275. data/src/core/support/time_precise.h +42 -0
  276. data/src/core/support/time_win32.c +101 -0
  277. data/src/core/support/tls_pthread.c +45 -0
  278. data/src/core/surface/api_trace.c +36 -0
  279. data/src/core/surface/api_trace.h +65 -0
  280. data/src/core/surface/byte_buffer.c +97 -0
  281. data/src/core/surface/byte_buffer_reader.c +123 -0
  282. data/src/core/surface/call.c +1424 -0
  283. data/src/core/surface/call.h +109 -0
  284. data/src/core/surface/call_details.c +50 -0
  285. data/src/core/surface/call_log_batch.c +118 -0
  286. data/src/core/surface/call_test_only.h +64 -0
  287. data/src/core/surface/channel.c +327 -0
  288. data/src/core/surface/channel.h +74 -0
  289. data/src/core/surface/channel_connectivity.c +220 -0
  290. data/src/core/surface/channel_create.c +235 -0
  291. data/src/core/surface/channel_ping.c +79 -0
  292. data/src/core/surface/completion_queue.c +481 -0
  293. data/src/core/surface/completion_queue.h +91 -0
  294. data/src/core/surface/event_string.c +81 -0
  295. data/src/core/surface/event_string.h +42 -0
  296. data/src/core/surface/init.c +168 -0
  297. data/src/core/surface/init.h +40 -0
  298. data/src/core/surface/init_secure.c +42 -0
  299. data/src/core/surface/lame_client.c +149 -0
  300. data/src/core/surface/metadata_array.c +49 -0
  301. data/src/core/surface/secure_channel_create.c +336 -0
  302. data/src/core/surface/server.c +1343 -0
  303. data/src/core/surface/server.h +67 -0
  304. data/src/core/surface/server_chttp2.c +149 -0
  305. data/src/core/surface/server_create.c +51 -0
  306. data/src/core/surface/surface_trace.h +48 -0
  307. data/src/core/surface/validate_metadata.c +73 -0
  308. data/src/core/surface/version.c +39 -0
  309. data/src/core/transport/byte_stream.c +76 -0
  310. data/src/core/transport/byte_stream.h +88 -0
  311. data/src/core/transport/chttp2/alpn.c +56 -0
  312. data/src/core/transport/chttp2/alpn.h +49 -0
  313. data/src/core/transport/chttp2/bin_encoder.c +285 -0
  314. data/src/core/transport/chttp2/bin_encoder.h +54 -0
  315. data/src/core/transport/chttp2/frame.h +69 -0
  316. data/src/core/transport/chttp2/frame_data.c +245 -0
  317. data/src/core/transport/chttp2/frame_data.h +101 -0
  318. data/src/core/transport/chttp2/frame_goaway.c +193 -0
  319. data/src/core/transport/chttp2/frame_goaway.h +77 -0
  320. data/src/core/transport/chttp2/frame_ping.c +97 -0
  321. data/src/core/transport/chttp2/frame_ping.h +56 -0
  322. data/src/core/transport/chttp2/frame_rst_stream.c +100 -0
  323. data/src/core/transport/chttp2/frame_rst_stream.h +55 -0
  324. data/src/core/transport/chttp2/frame_settings.c +259 -0
  325. data/src/core/transport/chttp2/frame_settings.h +103 -0
  326. data/src/core/transport/chttp2/frame_window_update.c +114 -0
  327. data/src/core/transport/chttp2/frame_window_update.h +58 -0
  328. data/src/core/transport/chttp2/hpack_encoder.c +572 -0
  329. data/src/core/transport/chttp2/hpack_encoder.h +95 -0
  330. data/src/core/transport/chttp2/hpack_parser.c +1449 -0
  331. data/src/core/transport/chttp2/hpack_parser.h +116 -0
  332. data/src/core/transport/chttp2/hpack_table.c +361 -0
  333. data/src/core/transport/chttp2/hpack_table.h +108 -0
  334. data/src/core/transport/chttp2/http2_errors.h +56 -0
  335. data/src/core/transport/chttp2/huffsyms.c +297 -0
  336. data/src/core/transport/chttp2/huffsyms.h +48 -0
  337. data/src/core/transport/chttp2/incoming_metadata.c +96 -0
  338. data/src/core/transport/chttp2/incoming_metadata.h +60 -0
  339. data/src/core/transport/chttp2/internal.h +757 -0
  340. data/src/core/transport/chttp2/parsing.c +866 -0
  341. data/src/core/transport/chttp2/status_conversion.c +109 -0
  342. data/src/core/transport/chttp2/status_conversion.h +50 -0
  343. data/src/core/transport/chttp2/stream_lists.c +401 -0
  344. data/src/core/transport/chttp2/stream_map.c +198 -0
  345. data/src/core/transport/chttp2/stream_map.h +85 -0
  346. data/src/core/transport/chttp2/timeout_encoding.c +185 -0
  347. data/src/core/transport/chttp2/timeout_encoding.h +47 -0
  348. data/src/core/transport/chttp2/varint.c +66 -0
  349. data/src/core/transport/chttp2/varint.h +76 -0
  350. data/src/core/transport/chttp2/writing.c +356 -0
  351. data/src/core/transport/chttp2_transport.c +1692 -0
  352. data/src/core/transport/chttp2_transport.h +51 -0
  353. data/src/core/transport/connectivity_state.c +164 -0
  354. data/src/core/transport/connectivity_state.h +85 -0
  355. data/src/core/transport/metadata.c +690 -0
  356. data/src/core/transport/metadata.h +156 -0
  357. data/src/core/transport/metadata_batch.c +194 -0
  358. data/src/core/transport/metadata_batch.h +125 -0
  359. data/src/core/transport/static_metadata.c +90 -0
  360. data/src/core/transport/static_metadata.h +408 -0
  361. data/src/core/transport/transport.c +183 -0
  362. data/src/core/transport/transport.h +222 -0
  363. data/src/core/transport/transport_impl.h +78 -0
  364. data/src/core/transport/transport_op_string.c +140 -0
  365. data/src/core/tsi/fake_transport_security.c +525 -0
  366. data/src/core/tsi/fake_transport_security.h +61 -0
  367. data/src/core/tsi/ssl_transport_security.c +1467 -0
  368. data/src/core/tsi/ssl_transport_security.h +173 -0
  369. data/src/core/tsi/transport_security.c +284 -0
  370. data/src/core/tsi/transport_security.h +111 -0
  371. data/src/core/tsi/transport_security_interface.h +344 -0
  372. data/{bin → src/ruby/bin}/apis/google/protobuf/empty.rb +0 -0
  373. data/{bin → src/ruby/bin}/apis/pubsub_demo.rb +7 -15
  374. data/{bin → src/ruby/bin}/apis/tech/pubsub/proto/pubsub.rb +0 -0
  375. data/{bin → src/ruby/bin}/apis/tech/pubsub/proto/pubsub_services.rb +0 -0
  376. data/{bin → src/ruby/bin}/grpc_ruby_interop_client +0 -0
  377. data/{bin → src/ruby/bin}/grpc_ruby_interop_server +0 -0
  378. data/{bin → src/ruby/bin}/interop/interop_client.rb +0 -0
  379. data/{bin → src/ruby/bin}/interop/interop_server.rb +0 -0
  380. data/src/ruby/bin/math.rb +32 -0
  381. data/{bin → src/ruby/bin}/math_client.rb +1 -1
  382. data/{bin → src/ruby/bin}/math_server.rb +1 -1
  383. data/src/ruby/bin/math_services.rb +27 -0
  384. data/{bin → src/ruby/bin}/noproto_client.rb +1 -1
  385. data/{bin → src/ruby/bin}/noproto_server.rb +1 -1
  386. data/{ext → src/ruby/ext}/grpc/extconf.rb +24 -40
  387. data/{ext → src/ruby/ext}/grpc/rb_byte_buffer.c +0 -0
  388. data/{ext → src/ruby/ext}/grpc/rb_byte_buffer.h +0 -0
  389. data/{ext → src/ruby/ext}/grpc/rb_call.c +80 -18
  390. data/{ext → src/ruby/ext}/grpc/rb_call.h +6 -0
  391. data/src/ruby/ext/grpc/rb_call_credentials.c +315 -0
  392. data/src/ruby/ext/grpc/rb_call_credentials.h +46 -0
  393. data/{ext → src/ruby/ext}/grpc/rb_channel.c +19 -7
  394. data/{ext → src/ruby/ext}/grpc/rb_channel.h +0 -0
  395. data/{ext → src/ruby/ext}/grpc/rb_channel_args.c +2 -0
  396. data/{ext → src/ruby/ext}/grpc/rb_channel_args.h +0 -0
  397. data/src/ruby/ext/grpc/rb_channel_credentials.c +266 -0
  398. data/{ext/grpc/rb_credentials.h → src/ruby/ext/grpc/rb_channel_credentials.h} +3 -3
  399. data/{ext → src/ruby/ext}/grpc/rb_completion_queue.c +3 -1
  400. data/{ext → src/ruby/ext}/grpc/rb_completion_queue.h +0 -0
  401. data/src/ruby/ext/grpc/rb_event_thread.c +153 -0
  402. data/src/ruby/ext/grpc/rb_event_thread.h +37 -0
  403. data/{ext → src/ruby/ext}/grpc/rb_grpc.c +25 -5
  404. data/{ext → src/ruby/ext}/grpc/rb_grpc.h +0 -0
  405. data/{ext → src/ruby/ext}/grpc/rb_server.c +4 -1
  406. data/{ext → src/ruby/ext}/grpc/rb_server.h +0 -0
  407. data/{ext → src/ruby/ext}/grpc/rb_server_credentials.c +2 -0
  408. data/{ext → src/ruby/ext}/grpc/rb_server_credentials.h +0 -0
  409. data/{lib → src/ruby/lib}/grpc.rb +6 -1
  410. data/{lib → src/ruby/lib}/grpc/core/time_consts.rb +0 -0
  411. data/{lib → src/ruby/lib}/grpc/errors.rb +0 -0
  412. data/{lib → src/ruby/lib}/grpc/generic/active_call.rb +4 -6
  413. data/{lib → src/ruby/lib}/grpc/generic/bidi_call.rb +16 -4
  414. data/{lib → src/ruby/lib}/grpc/generic/client_stub.rb +42 -52
  415. data/{lib → src/ruby/lib}/grpc/generic/rpc_desc.rb +0 -0
  416. data/{lib → src/ruby/lib}/grpc/generic/rpc_server.rb +15 -8
  417. data/{lib → src/ruby/lib}/grpc/generic/service.rb +4 -2
  418. data/src/ruby/lib/grpc/grpc.so +0 -0
  419. data/{lib → src/ruby/lib}/grpc/logconfig.rb +0 -0
  420. data/{lib → src/ruby/lib}/grpc/notifier.rb +0 -0
  421. data/{lib → src/ruby/lib}/grpc/version.rb +2 -2
  422. data/src/ruby/pb/README.md +42 -0
  423. data/src/ruby/pb/generate_proto_ruby.sh +51 -0
  424. data/src/ruby/pb/grpc/health/checker.rb +75 -0
  425. data/src/ruby/pb/grpc/health/v1alpha/health.rb +29 -0
  426. data/src/ruby/pb/grpc/health/v1alpha/health_services.rb +28 -0
  427. data/src/ruby/pb/test/client.rb +469 -0
  428. data/src/ruby/pb/test/proto/empty.rb +15 -0
  429. data/src/ruby/pb/test/proto/messages.rb +80 -0
  430. data/src/ruby/pb/test/proto/test.rb +14 -0
  431. data/src/ruby/pb/test/proto/test_services.rb +64 -0
  432. data/src/ruby/pb/test/server.rb +253 -0
  433. data/{bin/math_services.rb → src/ruby/spec/call_credentials_spec.rb} +19 -18
  434. data/{spec → src/ruby/spec}/call_spec.rb +10 -1
  435. data/{spec/credentials_spec.rb → src/ruby/spec/channel_credentials_spec.rb} +38 -12
  436. data/{spec → src/ruby/spec}/channel_spec.rb +14 -9
  437. data/{spec → src/ruby/spec}/client_server_spec.rb +31 -2
  438. data/{spec → src/ruby/spec}/completion_queue_spec.rb +0 -0
  439. data/{spec → src/ruby/spec}/generic/active_call_spec.rb +2 -1
  440. data/{spec → src/ruby/spec}/generic/client_stub_spec.rb +27 -67
  441. data/{spec → src/ruby/spec}/generic/rpc_desc_spec.rb +0 -0
  442. data/{spec → src/ruby/spec}/generic/rpc_server_pool_spec.rb +0 -0
  443. data/{spec → src/ruby/spec}/generic/rpc_server_spec.rb +12 -46
  444. data/{spec → src/ruby/spec}/generic/service_spec.rb +6 -3
  445. data/{spec → src/ruby/spec}/pb/health/checker_spec.rb +8 -8
  446. data/{spec → src/ruby/spec}/server_credentials_spec.rb +0 -0
  447. data/{spec → src/ruby/spec}/server_spec.rb +0 -0
  448. data/{spec → src/ruby/spec}/spec_helper.rb +0 -0
  449. data/{spec → src/ruby/spec}/testdata/README +0 -0
  450. data/{spec → src/ruby/spec}/testdata/ca.pem +0 -0
  451. data/{spec → src/ruby/spec}/testdata/server1.key +0 -0
  452. data/src/ruby/spec/testdata/server1.pem +16 -0
  453. data/{spec → src/ruby/spec}/time_consts_spec.rb +0 -0
  454. metadata +496 -97
  455. data/bin/math.proto +0 -80
  456. data/bin/math.rb +0 -61
  457. data/ext/grpc/rb_credentials.c +0 -294
  458. data/lib/grpc/grpc.so +0 -0
  459. data/spec/testdata/server1.pem +0 -16
@@ -0,0 +1,1343 @@
1
+ /*
2
+ *
3
+ * Copyright 2015, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #include "src/core/surface/server.h"
35
+
36
+ #include <limits.h>
37
+ #include <stdlib.h>
38
+ #include <string.h>
39
+
40
+ #include <grpc/support/alloc.h>
41
+ #include <grpc/support/log.h>
42
+ #include <grpc/support/string_util.h>
43
+ #include <grpc/support/useful.h>
44
+
45
+ #include "src/core/census/grpc_filter.h"
46
+ #include "src/core/channel/channel_args.h"
47
+ #include "src/core/channel/connected_channel.h"
48
+ #include "src/core/iomgr/iomgr.h"
49
+ #include "src/core/support/stack_lockfree.h"
50
+ #include "src/core/support/string.h"
51
+ #include "src/core/surface/api_trace.h"
52
+ #include "src/core/surface/call.h"
53
+ #include "src/core/surface/channel.h"
54
+ #include "src/core/surface/completion_queue.h"
55
+ #include "src/core/surface/init.h"
56
+ #include "src/core/transport/metadata.h"
57
+ #include "src/core/transport/static_metadata.h"
58
+
59
+ typedef struct listener {
60
+ void *arg;
61
+ void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
62
+ grpc_pollset **pollsets, size_t pollset_count);
63
+ void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
64
+ grpc_closure *closure);
65
+ struct listener *next;
66
+ grpc_closure destroy_done;
67
+ } listener;
68
+
69
+ typedef struct call_data call_data;
70
+ typedef struct channel_data channel_data;
71
+ typedef struct registered_method registered_method;
72
+
73
+ typedef struct {
74
+ call_data *next;
75
+ call_data *prev;
76
+ } call_link;
77
+
78
+ typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type;
79
+
80
+ typedef struct requested_call {
81
+ requested_call_type type;
82
+ void *tag;
83
+ grpc_server *server;
84
+ grpc_completion_queue *cq_bound_to_call;
85
+ grpc_completion_queue *cq_for_notification;
86
+ grpc_call **call;
87
+ grpc_cq_completion completion;
88
+ grpc_metadata_array *initial_metadata;
89
+ union {
90
+ struct {
91
+ grpc_call_details *details;
92
+ } batch;
93
+ struct {
94
+ registered_method *registered_method;
95
+ gpr_timespec *deadline;
96
+ grpc_byte_buffer **optional_payload;
97
+ } registered;
98
+ } data;
99
+ grpc_closure publish;
100
+ } requested_call;
101
+
102
+ typedef struct channel_registered_method {
103
+ registered_method *server_registered_method;
104
+ grpc_mdstr *method;
105
+ grpc_mdstr *host;
106
+ } channel_registered_method;
107
+
108
+ struct channel_data {
109
+ grpc_server *server;
110
+ grpc_connectivity_state connectivity_state;
111
+ grpc_channel *channel;
112
+ /* linked list of all channels on a server */
113
+ channel_data *next;
114
+ channel_data *prev;
115
+ channel_registered_method *registered_methods;
116
+ gpr_uint32 registered_method_slots;
117
+ gpr_uint32 registered_method_max_probes;
118
+ grpc_closure finish_destroy_channel_closure;
119
+ grpc_closure channel_connectivity_changed;
120
+ };
121
+
122
+ typedef struct shutdown_tag {
123
+ void *tag;
124
+ grpc_completion_queue *cq;
125
+ grpc_cq_completion completion;
126
+ } shutdown_tag;
127
+
128
+ typedef enum {
129
+ /* waiting for metadata */
130
+ NOT_STARTED,
131
+ /* inital metadata read, not flow controlled in yet */
132
+ PENDING,
133
+ /* flow controlled in, on completion queue */
134
+ ACTIVATED,
135
+ /* cancelled before being queued */
136
+ ZOMBIED
137
+ } call_state;
138
+
139
+ typedef struct request_matcher request_matcher;
140
+
141
+ struct call_data {
142
+ grpc_call *call;
143
+
144
+ /** protects state */
145
+ gpr_mu mu_state;
146
+ /** the current state of a call - see call_state */
147
+ call_state state;
148
+
149
+ grpc_mdstr *path;
150
+ grpc_mdstr *host;
151
+ gpr_timespec deadline;
152
+
153
+ grpc_completion_queue *cq_new;
154
+
155
+ grpc_metadata_batch *recv_initial_metadata;
156
+ grpc_metadata_array initial_metadata;
157
+
158
+ grpc_closure got_initial_metadata;
159
+ grpc_closure server_on_recv_initial_metadata;
160
+ grpc_closure kill_zombie_closure;
161
+ grpc_closure *on_done_recv_initial_metadata;
162
+
163
+ call_data *pending_next;
164
+ };
165
+
166
+ struct request_matcher {
167
+ call_data *pending_head;
168
+ call_data *pending_tail;
169
+ gpr_stack_lockfree *requests;
170
+ };
171
+
172
+ struct registered_method {
173
+ char *method;
174
+ char *host;
175
+ request_matcher request_matcher;
176
+ registered_method *next;
177
+ };
178
+
179
+ typedef struct {
180
+ grpc_channel **channels;
181
+ size_t num_channels;
182
+ } channel_broadcaster;
183
+
184
+ struct grpc_server {
185
+ size_t channel_filter_count;
186
+ grpc_channel_filter const **channel_filters;
187
+ grpc_channel_args *channel_args;
188
+
189
+ grpc_completion_queue **cqs;
190
+ grpc_pollset **pollsets;
191
+ size_t cq_count;
192
+
193
+ /* The two following mutexes control access to server-state
194
+ mu_global controls access to non-call-related state (e.g., channel state)
195
+ mu_call controls access to call-related state (e.g., the call lists)
196
+
197
+ If they are ever required to be nested, you must lock mu_global
198
+ before mu_call. This is currently used in shutdown processing
199
+ (grpc_server_shutdown_and_notify and maybe_finish_shutdown) */
200
+ gpr_mu mu_global; /* mutex for server and channel state */
201
+ gpr_mu mu_call; /* mutex for call-specific state */
202
+
203
+ registered_method *registered_methods;
204
+ request_matcher unregistered_request_matcher;
205
+ /** free list of available requested_calls indices */
206
+ gpr_stack_lockfree *request_freelist;
207
+ /** requested call backing data */
208
+ requested_call *requested_calls;
209
+ size_t max_requested_calls;
210
+
211
+ gpr_atm shutdown_flag;
212
+ gpr_uint8 shutdown_published;
213
+ size_t num_shutdown_tags;
214
+ shutdown_tag *shutdown_tags;
215
+
216
+ channel_data root_channel_data;
217
+
218
+ listener *listeners;
219
+ int listeners_destroyed;
220
+ gpr_refcount internal_refcount;
221
+
222
+ /** when did we print the last shutdown progress message */
223
+ gpr_timespec last_shutdown_message_time;
224
+ };
225
+
226
+ #define SERVER_FROM_CALL_ELEM(elem) \
227
+ (((channel_data *)(elem)->channel_data)->server)
228
+
229
+ static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
230
+ call_data *calld, requested_call *rc);
231
+ static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
232
+ requested_call *rc);
233
+ /* Before calling maybe_finish_shutdown, we must hold mu_global and not
234
+ hold mu_call */
235
+ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server);
236
+
237
+ /*
238
+ * channel broadcaster
239
+ */
240
+
241
+ /* assumes server locked */
242
+ static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) {
243
+ channel_data *c;
244
+ size_t count = 0;
245
+ for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
246
+ count++;
247
+ }
248
+ cb->num_channels = count;
249
+ cb->channels = gpr_malloc(sizeof(*cb->channels) * cb->num_channels);
250
+ count = 0;
251
+ for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
252
+ cb->channels[count++] = c->channel;
253
+ GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast");
254
+ }
255
+ }
256
+
257
+ struct shutdown_cleanup_args {
258
+ grpc_closure closure;
259
+ gpr_slice slice;
260
+ };
261
+
262
+ static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
263
+ int iomgr_status_ignored) {
264
+ struct shutdown_cleanup_args *a = arg;
265
+ gpr_slice_unref(a->slice);
266
+ gpr_free(a);
267
+ }
268
+
269
+ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
270
+ int send_goaway, int send_disconnect) {
271
+ grpc_transport_op op;
272
+ struct shutdown_cleanup_args *sc;
273
+ grpc_channel_element *elem;
274
+
275
+ memset(&op, 0, sizeof(op));
276
+ op.send_goaway = send_goaway;
277
+ sc = gpr_malloc(sizeof(*sc));
278
+ sc->slice = gpr_slice_from_copied_string("Server shutdown");
279
+ op.goaway_message = &sc->slice;
280
+ op.goaway_status = GRPC_STATUS_OK;
281
+ op.disconnect = send_disconnect;
282
+ grpc_closure_init(&sc->closure, shutdown_cleanup, sc);
283
+ op.on_consumed = &sc->closure;
284
+
285
+ elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
286
+ elem->filter->start_transport_op(exec_ctx, elem, &op);
287
+ }
288
+
289
+ static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx,
290
+ channel_broadcaster *cb,
291
+ int send_goaway,
292
+ int force_disconnect) {
293
+ size_t i;
294
+
295
+ for (i = 0; i < cb->num_channels; i++) {
296
+ send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect);
297
+ GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast");
298
+ }
299
+ gpr_free(cb->channels);
300
+ }
301
+
302
+ /*
303
+ * request_matcher
304
+ */
305
+
306
+ static void request_matcher_init(request_matcher *rm, size_t entries) {
307
+ memset(rm, 0, sizeof(*rm));
308
+ rm->requests = gpr_stack_lockfree_create(entries);
309
+ }
310
+
311
+ static void request_matcher_destroy(request_matcher *rm) {
312
+ GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests) == -1);
313
+ gpr_stack_lockfree_destroy(rm->requests);
314
+ }
315
+
316
+ static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, int success) {
317
+ grpc_call_destroy(grpc_call_from_top_element(elem));
318
+ }
319
+
320
+ static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx,
321
+ request_matcher *rm) {
322
+ while (rm->pending_head) {
323
+ call_data *calld = rm->pending_head;
324
+ rm->pending_head = calld->pending_next;
325
+ gpr_mu_lock(&calld->mu_state);
326
+ calld->state = ZOMBIED;
327
+ gpr_mu_unlock(&calld->mu_state);
328
+ grpc_closure_init(
329
+ &calld->kill_zombie_closure, kill_zombie,
330
+ grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
331
+ grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
332
+ }
333
+ }
334
+
335
+ static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx,
336
+ grpc_server *server,
337
+ request_matcher *rm) {
338
+ int request_id;
339
+ while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) {
340
+ fail_call(exec_ctx, server, &server->requested_calls[request_id]);
341
+ }
342
+ }
343
+
344
+ /*
345
+ * server proper
346
+ */
347
+
348
+ static void server_ref(grpc_server *server) {
349
+ gpr_ref(&server->internal_refcount);
350
+ }
351
+
352
+ static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
353
+ registered_method *rm;
354
+ size_t i;
355
+ grpc_channel_args_destroy(server->channel_args);
356
+ gpr_mu_destroy(&server->mu_global);
357
+ gpr_mu_destroy(&server->mu_call);
358
+ gpr_free((void *)server->channel_filters);
359
+ while ((rm = server->registered_methods) != NULL) {
360
+ server->registered_methods = rm->next;
361
+ request_matcher_destroy(&rm->request_matcher);
362
+ gpr_free(rm->method);
363
+ gpr_free(rm->host);
364
+ gpr_free(rm);
365
+ }
366
+ for (i = 0; i < server->cq_count; i++) {
367
+ GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server");
368
+ }
369
+ request_matcher_destroy(&server->unregistered_request_matcher);
370
+ gpr_stack_lockfree_destroy(server->request_freelist);
371
+ gpr_free(server->cqs);
372
+ gpr_free(server->pollsets);
373
+ gpr_free(server->shutdown_tags);
374
+ gpr_free(server->requested_calls);
375
+ gpr_free(server);
376
+ }
377
+
378
+ static void server_unref(grpc_exec_ctx *exec_ctx, grpc_server *server) {
379
+ if (gpr_unref(&server->internal_refcount)) {
380
+ server_delete(exec_ctx, server);
381
+ }
382
+ }
383
+
384
+ static int is_channel_orphaned(channel_data *chand) {
385
+ return chand->next == chand;
386
+ }
387
+
388
+ static void orphan_channel(channel_data *chand) {
389
+ chand->next->prev = chand->prev;
390
+ chand->prev->next = chand->next;
391
+ chand->next = chand->prev = chand;
392
+ }
393
+
394
+ static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd,
395
+ int success) {
396
+ channel_data *chand = cd;
397
+ grpc_server *server = chand->server;
398
+ GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server");
399
+ server_unref(exec_ctx, server);
400
+ }
401
+
402
+ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) {
403
+ if (is_channel_orphaned(chand)) return;
404
+ GPR_ASSERT(chand->server != NULL);
405
+ orphan_channel(chand);
406
+ server_ref(chand->server);
407
+ maybe_finish_shutdown(exec_ctx, chand->server);
408
+ chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
409
+ chand->finish_destroy_channel_closure.cb_arg = chand;
410
+ grpc_exec_ctx_enqueue(exec_ctx, &chand->finish_destroy_channel_closure, 1);
411
+ }
412
+
413
+ static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server,
414
+ grpc_call_element *elem, request_matcher *rm) {
415
+ call_data *calld = elem->call_data;
416
+ int request_id;
417
+
418
+ if (gpr_atm_acq_load(&server->shutdown_flag)) {
419
+ gpr_mu_lock(&calld->mu_state);
420
+ calld->state = ZOMBIED;
421
+ gpr_mu_unlock(&calld->mu_state);
422
+ grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
423
+ grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
424
+ return;
425
+ }
426
+
427
+ request_id = gpr_stack_lockfree_pop(rm->requests);
428
+ if (request_id == -1) {
429
+ gpr_mu_lock(&server->mu_call);
430
+ gpr_mu_lock(&calld->mu_state);
431
+ calld->state = PENDING;
432
+ gpr_mu_unlock(&calld->mu_state);
433
+ if (rm->pending_head == NULL) {
434
+ rm->pending_tail = rm->pending_head = calld;
435
+ } else {
436
+ rm->pending_tail->pending_next = calld;
437
+ rm->pending_tail = calld;
438
+ }
439
+ calld->pending_next = NULL;
440
+ gpr_mu_unlock(&server->mu_call);
441
+ } else {
442
+ gpr_mu_lock(&calld->mu_state);
443
+ calld->state = ACTIVATED;
444
+ gpr_mu_unlock(&calld->mu_state);
445
+ begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
446
+ }
447
+ }
448
+
449
+ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
450
+ channel_data *chand = elem->channel_data;
451
+ call_data *calld = elem->call_data;
452
+ grpc_server *server = chand->server;
453
+ gpr_uint32 i;
454
+ gpr_uint32 hash;
455
+ channel_registered_method *rm;
456
+
457
+ if (chand->registered_methods && calld->path && calld->host) {
458
+ /* TODO(ctiller): unify these two searches */
459
+ /* check for an exact match with host */
460
+ hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
461
+ for (i = 0; i <= chand->registered_method_max_probes; i++) {
462
+ rm = &chand->registered_methods[(hash + i) %
463
+ chand->registered_method_slots];
464
+ if (!rm) break;
465
+ if (rm->host != calld->host) continue;
466
+ if (rm->method != calld->path) continue;
467
+ finish_start_new_rpc(exec_ctx, server, elem,
468
+ &rm->server_registered_method->request_matcher);
469
+ return;
470
+ }
471
+ /* check for a wildcard method definition (no host set) */
472
+ hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
473
+ for (i = 0; i <= chand->registered_method_max_probes; i++) {
474
+ rm = &chand->registered_methods[(hash + i) %
475
+ chand->registered_method_slots];
476
+ if (!rm) break;
477
+ if (rm->host != NULL) continue;
478
+ if (rm->method != calld->path) continue;
479
+ finish_start_new_rpc(exec_ctx, server, elem,
480
+ &rm->server_registered_method->request_matcher);
481
+ return;
482
+ }
483
+ }
484
+ finish_start_new_rpc(exec_ctx, server, elem,
485
+ &server->unregistered_request_matcher);
486
+ }
487
+
488
+ static int num_listeners(grpc_server *server) {
489
+ listener *l;
490
+ int n = 0;
491
+ for (l = server->listeners; l; l = l->next) {
492
+ n++;
493
+ }
494
+ return n;
495
+ }
496
+
497
+ static void done_shutdown_event(grpc_exec_ctx *exec_ctx, void *server,
498
+ grpc_cq_completion *completion) {
499
+ server_unref(exec_ctx, server);
500
+ }
501
+
502
+ static int num_channels(grpc_server *server) {
503
+ channel_data *chand;
504
+ int n = 0;
505
+ for (chand = server->root_channel_data.next;
506
+ chand != &server->root_channel_data; chand = chand->next) {
507
+ n++;
508
+ }
509
+ return n;
510
+ }
511
+
512
+ static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx,
513
+ grpc_server *server) {
514
+ registered_method *rm;
515
+ request_matcher_kill_requests(exec_ctx, server,
516
+ &server->unregistered_request_matcher);
517
+ request_matcher_zombify_all_pending_calls(
518
+ exec_ctx, &server->unregistered_request_matcher);
519
+ for (rm = server->registered_methods; rm; rm = rm->next) {
520
+ request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher);
521
+ request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
522
+ }
523
+ }
524
+
525
+ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
526
+ grpc_server *server) {
527
+ size_t i;
528
+ if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) {
529
+ return;
530
+ }
531
+
532
+ kill_pending_work_locked(exec_ctx, server);
533
+
534
+ if (server->root_channel_data.next != &server->root_channel_data ||
535
+ server->listeners_destroyed < num_listeners(server)) {
536
+ if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
537
+ server->last_shutdown_message_time),
538
+ gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
539
+ server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
540
+ gpr_log(GPR_DEBUG,
541
+ "Waiting for %d channels and %d/%d listeners to be destroyed"
542
+ " before shutting down server",
543
+ num_channels(server),
544
+ num_listeners(server) - server->listeners_destroyed,
545
+ num_listeners(server));
546
+ }
547
+ return;
548
+ }
549
+ server->shutdown_published = 1;
550
+ for (i = 0; i < server->num_shutdown_tags; i++) {
551
+ server_ref(server);
552
+ grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq,
553
+ server->shutdown_tags[i].tag, 1, done_shutdown_event, server,
554
+ &server->shutdown_tags[i].completion);
555
+ }
556
+ }
557
+
558
+ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
559
+ grpc_call_element *elem = user_data;
560
+ call_data *calld = elem->call_data;
561
+ if (md->key == GRPC_MDSTR_PATH) {
562
+ calld->path = GRPC_MDSTR_REF(md->value);
563
+ return NULL;
564
+ } else if (md->key == GRPC_MDSTR_AUTHORITY) {
565
+ calld->host = GRPC_MDSTR_REF(md->value);
566
+ return NULL;
567
+ }
568
+ return md;
569
+ }
570
+
571
+ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
572
+ int success) {
573
+ grpc_call_element *elem = ptr;
574
+ call_data *calld = elem->call_data;
575
+ gpr_timespec op_deadline;
576
+
577
+ grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
578
+ op_deadline = calld->recv_initial_metadata->deadline;
579
+ if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
580
+ calld->deadline = op_deadline;
581
+ }
582
+ if (calld->host && calld->path) {
583
+ /* do nothing */
584
+ } else {
585
+ success = 0;
586
+ }
587
+
588
+ calld->on_done_recv_initial_metadata->cb(
589
+ exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success);
590
+ }
591
+
592
+ static void server_mutate_op(grpc_call_element *elem,
593
+ grpc_transport_stream_op *op) {
594
+ call_data *calld = elem->call_data;
595
+
596
+ if (op->recv_initial_metadata != NULL) {
597
+ calld->recv_initial_metadata = op->recv_initial_metadata;
598
+ calld->on_done_recv_initial_metadata = op->on_complete;
599
+ op->on_complete = &calld->server_on_recv_initial_metadata;
600
+ }
601
+ }
602
+
603
+ static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
604
+ grpc_call_element *elem,
605
+ grpc_transport_stream_op *op) {
606
+ GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
607
+ server_mutate_op(elem, op);
608
+ grpc_call_next_op(exec_ctx, elem, op);
609
+ }
610
+
611
+ static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
612
+ int success) {
613
+ grpc_call_element *elem = ptr;
614
+ call_data *calld = elem->call_data;
615
+ if (success) {
616
+ start_new_rpc(exec_ctx, elem);
617
+ } else {
618
+ gpr_mu_lock(&calld->mu_state);
619
+ if (calld->state == NOT_STARTED) {
620
+ calld->state = ZOMBIED;
621
+ gpr_mu_unlock(&calld->mu_state);
622
+ grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
623
+ grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
624
+ } else if (calld->state == PENDING) {
625
+ calld->state = ZOMBIED;
626
+ gpr_mu_unlock(&calld->mu_state);
627
+ /* zombied call will be destroyed when it's removed from the pending
628
+ queue... later */
629
+ } else {
630
+ gpr_mu_unlock(&calld->mu_state);
631
+ }
632
+ }
633
+ }
634
+
635
+ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
636
+ grpc_transport *transport,
637
+ const void *transport_server_data) {
638
+ channel_data *chand = cd;
639
+ /* create a call */
640
+ grpc_call *call =
641
+ grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data,
642
+ NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
643
+ grpc_call_element *elem =
644
+ grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
645
+ call_data *calld = elem->call_data;
646
+ grpc_op op;
647
+ memset(&op, 0, sizeof(op));
648
+ op.op = GRPC_OP_RECV_INITIAL_METADATA;
649
+ op.data.recv_initial_metadata = &calld->initial_metadata;
650
+ grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem);
651
+ grpc_call_start_batch_and_execute(exec_ctx, call, &op, 1,
652
+ &calld->got_initial_metadata);
653
+ }
654
+
655
+ static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd,
656
+ int iomgr_status_ignored) {
657
+ channel_data *chand = cd;
658
+ grpc_server *server = chand->server;
659
+ if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
660
+ grpc_transport_op op;
661
+ memset(&op, 0, sizeof(op));
662
+ op.on_connectivity_state_change = &chand->channel_connectivity_changed,
663
+ op.connectivity_state = &chand->connectivity_state;
664
+ grpc_channel_next_op(exec_ctx,
665
+ grpc_channel_stack_element(
666
+ grpc_channel_get_channel_stack(chand->channel), 0),
667
+ &op);
668
+ } else {
669
+ gpr_mu_lock(&server->mu_global);
670
+ destroy_channel(exec_ctx, chand);
671
+ gpr_mu_unlock(&server->mu_global);
672
+ GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity");
673
+ }
674
+ }
675
+
676
+ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
677
+ grpc_call_element_args *args) {
678
+ call_data *calld = elem->call_data;
679
+ channel_data *chand = elem->channel_data;
680
+ memset(calld, 0, sizeof(call_data));
681
+ calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
682
+ calld->call = grpc_call_from_top_element(elem);
683
+ gpr_mu_init(&calld->mu_state);
684
+
685
+ grpc_closure_init(&calld->server_on_recv_initial_metadata,
686
+ server_on_recv_initial_metadata, elem);
687
+
688
+ server_ref(chand->server);
689
+ }
690
+
691
+ static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
692
+ grpc_call_element *elem) {
693
+ channel_data *chand = elem->channel_data;
694
+ call_data *calld = elem->call_data;
695
+
696
+ GPR_ASSERT(calld->state != PENDING);
697
+
698
+ if (calld->host) {
699
+ GRPC_MDSTR_UNREF(calld->host);
700
+ }
701
+ if (calld->path) {
702
+ GRPC_MDSTR_UNREF(calld->path);
703
+ }
704
+ grpc_metadata_array_destroy(&calld->initial_metadata);
705
+
706
+ gpr_mu_destroy(&calld->mu_state);
707
+
708
+ server_unref(exec_ctx, chand->server);
709
+ }
710
+
711
+ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
712
+ grpc_channel_element *elem,
713
+ grpc_channel_element_args *args) {
714
+ channel_data *chand = elem->channel_data;
715
+ GPR_ASSERT(args->is_first);
716
+ GPR_ASSERT(!args->is_last);
717
+ chand->server = NULL;
718
+ chand->channel = NULL;
719
+ chand->next = chand->prev = chand;
720
+ chand->registered_methods = NULL;
721
+ chand->connectivity_state = GRPC_CHANNEL_IDLE;
722
+ grpc_closure_init(&chand->channel_connectivity_changed,
723
+ channel_connectivity_changed, chand);
724
+ }
725
+
726
+ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
727
+ grpc_channel_element *elem) {
728
+ size_t i;
729
+ channel_data *chand = elem->channel_data;
730
+ if (chand->registered_methods) {
731
+ for (i = 0; i < chand->registered_method_slots; i++) {
732
+ if (chand->registered_methods[i].method) {
733
+ GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
734
+ }
735
+ if (chand->registered_methods[i].host) {
736
+ GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
737
+ }
738
+ }
739
+ gpr_free(chand->registered_methods);
740
+ }
741
+ if (chand->server) {
742
+ gpr_mu_lock(&chand->server->mu_global);
743
+ chand->next->prev = chand->prev;
744
+ chand->prev->next = chand->next;
745
+ chand->next = chand->prev = chand;
746
+ maybe_finish_shutdown(exec_ctx, chand->server);
747
+ gpr_mu_unlock(&chand->server->mu_global);
748
+ server_unref(exec_ctx, chand->server);
749
+ }
750
+ }
751
+
752
+ static const grpc_channel_filter server_surface_filter = {
753
+ server_start_transport_stream_op, grpc_channel_next_op, sizeof(call_data),
754
+ init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem,
755
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem,
756
+ grpc_call_next_get_peer, "server",
757
+ };
758
+
759
+ void grpc_server_register_completion_queue(grpc_server *server,
760
+ grpc_completion_queue *cq,
761
+ void *reserved) {
762
+ size_t i, n;
763
+ GRPC_API_TRACE(
764
+ "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
765
+ (server, cq, reserved));
766
+ GPR_ASSERT(!reserved);
767
+ for (i = 0; i < server->cq_count; i++) {
768
+ if (server->cqs[i] == cq) return;
769
+ }
770
+ GRPC_CQ_INTERNAL_REF(cq, "server");
771
+ grpc_cq_mark_server_cq(cq);
772
+ n = server->cq_count++;
773
+ server->cqs = gpr_realloc(server->cqs,
774
+ server->cq_count * sizeof(grpc_completion_queue *));
775
+ server->cqs[n] = cq;
776
+ }
777
+
778
+ grpc_server *grpc_server_create_from_filters(
779
+ const grpc_channel_filter **filters, size_t filter_count,
780
+ const grpc_channel_args *args) {
781
+ size_t i;
782
+ /* TODO(census): restore this once we finalize census filter etc.
783
+ int census_enabled = grpc_channel_args_is_census_enabled(args); */
784
+ int census_enabled = 0;
785
+
786
+ grpc_server *server = gpr_malloc(sizeof(grpc_server));
787
+
788
+ GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
789
+
790
+ memset(server, 0, sizeof(grpc_server));
791
+
792
+ gpr_mu_init(&server->mu_global);
793
+ gpr_mu_init(&server->mu_call);
794
+
795
+ /* decremented by grpc_server_destroy */
796
+ gpr_ref_init(&server->internal_refcount, 1);
797
+ server->root_channel_data.next = server->root_channel_data.prev =
798
+ &server->root_channel_data;
799
+
800
+ /* TODO(ctiller): expose a channel_arg for this */
801
+ server->max_requested_calls = 32768;
802
+ server->request_freelist =
803
+ gpr_stack_lockfree_create(server->max_requested_calls);
804
+ for (i = 0; i < (size_t)server->max_requested_calls; i++) {
805
+ gpr_stack_lockfree_push(server->request_freelist, (int)i);
806
+ }
807
+ request_matcher_init(&server->unregistered_request_matcher,
808
+ server->max_requested_calls);
809
+ server->requested_calls = gpr_malloc(server->max_requested_calls *
810
+ sizeof(*server->requested_calls));
811
+
812
+ /* Server filter stack is:
813
+
814
+ server_surface_filter - for making surface API calls
815
+ grpc_server_census_filter (optional) - for stats collection and tracing
816
+ {passed in filter stack}
817
+ grpc_connected_channel_filter - for interfacing with transports */
818
+ server->channel_filter_count = filter_count + 1u + (census_enabled ? 1u : 0u);
819
+ server->channel_filters =
820
+ gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *));
821
+ server->channel_filters[0] = &server_surface_filter;
822
+ if (census_enabled) {
823
+ server->channel_filters[1] = &grpc_server_census_filter;
824
+ }
825
+ for (i = 0; i < filter_count; i++) {
826
+ server->channel_filters[i + 1u + (census_enabled ? 1u : 0u)] = filters[i];
827
+ }
828
+
829
+ server->channel_args = grpc_channel_args_copy(args);
830
+
831
+ return server;
832
+ }
833
+
834
+ static int streq(const char *a, const char *b) {
835
+ if (a == NULL && b == NULL) return 1;
836
+ if (a == NULL) return 0;
837
+ if (b == NULL) return 0;
838
+ return 0 == strcmp(a, b);
839
+ }
840
+
841
+ void *grpc_server_register_method(grpc_server *server, const char *method,
842
+ const char *host) {
843
+ registered_method *m;
844
+ GRPC_API_TRACE("grpc_server_register_method(server=%p, method=%s, host=%s)",
845
+ 3, (server, method, host));
846
+ if (!method) {
847
+ gpr_log(GPR_ERROR,
848
+ "grpc_server_register_method method string cannot be NULL");
849
+ return NULL;
850
+ }
851
+ for (m = server->registered_methods; m; m = m->next) {
852
+ if (streq(m->method, method) && streq(m->host, host)) {
853
+ gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
854
+ host ? host : "*");
855
+ return NULL;
856
+ }
857
+ }
858
+ m = gpr_malloc(sizeof(registered_method));
859
+ memset(m, 0, sizeof(*m));
860
+ request_matcher_init(&m->request_matcher, server->max_requested_calls);
861
+ m->method = gpr_strdup(method);
862
+ m->host = gpr_strdup(host);
863
+ m->next = server->registered_methods;
864
+ server->registered_methods = m;
865
+ return m;
866
+ }
867
+
868
+ void grpc_server_start(grpc_server *server) {
869
+ listener *l;
870
+ size_t i;
871
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
872
+
873
+ GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
874
+
875
+ server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
876
+ for (i = 0; i < server->cq_count; i++) {
877
+ server->pollsets[i] = grpc_cq_pollset(server->cqs[i]);
878
+ }
879
+
880
+ for (l = server->listeners; l; l = l->next) {
881
+ l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count);
882
+ }
883
+
884
+ grpc_exec_ctx_finish(&exec_ctx);
885
+ }
886
+
887
+ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
888
+ grpc_transport *transport,
889
+ grpc_channel_filter const **extra_filters,
890
+ size_t num_extra_filters,
891
+ const grpc_channel_args *args) {
892
+ size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
893
+ grpc_channel_filter const **filters =
894
+ gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
895
+ size_t i;
896
+ size_t num_registered_methods;
897
+ size_t alloc;
898
+ registered_method *rm;
899
+ channel_registered_method *crm;
900
+ grpc_channel *channel;
901
+ channel_data *chand;
902
+ grpc_mdstr *host;
903
+ grpc_mdstr *method;
904
+ gpr_uint32 hash;
905
+ size_t slots;
906
+ gpr_uint32 probes;
907
+ gpr_uint32 max_probes = 0;
908
+ grpc_transport_op op;
909
+
910
+ for (i = 0; i < s->channel_filter_count; i++) {
911
+ filters[i] = s->channel_filters[i];
912
+ }
913
+ for (; i < s->channel_filter_count + num_extra_filters; i++) {
914
+ filters[i] = extra_filters[i - s->channel_filter_count];
915
+ }
916
+ filters[i] = &grpc_connected_channel_filter;
917
+
918
+ for (i = 0; i < s->cq_count; i++) {
919
+ memset(&op, 0, sizeof(op));
920
+ op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
921
+ grpc_transport_perform_op(exec_ctx, transport, &op);
922
+ }
923
+
924
+ channel = grpc_channel_create_from_filters(exec_ctx, NULL, filters,
925
+ num_filters, args, 0);
926
+ chand = (channel_data *)grpc_channel_stack_element(
927
+ grpc_channel_get_channel_stack(channel), 0)->channel_data;
928
+ chand->server = s;
929
+ server_ref(s);
930
+ chand->channel = channel;
931
+
932
+ num_registered_methods = 0;
933
+ for (rm = s->registered_methods; rm; rm = rm->next) {
934
+ num_registered_methods++;
935
+ }
936
+ /* build a lookup table phrased in terms of mdstr's in this channels context
937
+ to quickly find registered methods */
938
+ if (num_registered_methods > 0) {
939
+ slots = 2 * num_registered_methods;
940
+ alloc = sizeof(channel_registered_method) * slots;
941
+ chand->registered_methods = gpr_malloc(alloc);
942
+ memset(chand->registered_methods, 0, alloc);
943
+ for (rm = s->registered_methods; rm; rm = rm->next) {
944
+ host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL;
945
+ method = grpc_mdstr_from_string(rm->method);
946
+ hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
947
+ for (probes = 0; chand->registered_methods[(hash + probes) % slots]
948
+ .server_registered_method != NULL;
949
+ probes++)
950
+ ;
951
+ if (probes > max_probes) max_probes = probes;
952
+ crm = &chand->registered_methods[(hash + probes) % slots];
953
+ crm->server_registered_method = rm;
954
+ crm->host = host;
955
+ crm->method = method;
956
+ }
957
+ GPR_ASSERT(slots <= GPR_UINT32_MAX);
958
+ chand->registered_method_slots = (gpr_uint32)slots;
959
+ chand->registered_method_max_probes = max_probes;
960
+ }
961
+
962
+ grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
963
+ transport);
964
+
965
+ gpr_mu_lock(&s->mu_global);
966
+ chand->next = &s->root_channel_data;
967
+ chand->prev = chand->next->prev;
968
+ chand->next->prev = chand->prev->next = chand;
969
+ gpr_mu_unlock(&s->mu_global);
970
+
971
+ gpr_free((void *)filters);
972
+
973
+ GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity");
974
+ memset(&op, 0, sizeof(op));
975
+ op.set_accept_stream = accept_stream;
976
+ op.set_accept_stream_user_data = chand;
977
+ op.on_connectivity_state_change = &chand->channel_connectivity_changed;
978
+ op.connectivity_state = &chand->connectivity_state;
979
+ op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0;
980
+ grpc_transport_perform_op(exec_ctx, transport, &op);
981
+ }
982
+
983
+ void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg,
984
+ grpc_cq_completion *storage) {
985
+ (void)done_arg;
986
+ gpr_free(storage);
987
+ }
988
+
989
+ static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s,
990
+ int success) {
991
+ grpc_server *server = s;
992
+ gpr_mu_lock(&server->mu_global);
993
+ server->listeners_destroyed++;
994
+ maybe_finish_shutdown(exec_ctx, server);
995
+ gpr_mu_unlock(&server->mu_global);
996
+ }
997
+
998
+ void grpc_server_shutdown_and_notify(grpc_server *server,
999
+ grpc_completion_queue *cq, void *tag) {
1000
+ listener *l;
1001
+ shutdown_tag *sdt;
1002
+ channel_broadcaster broadcaster;
1003
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
1004
+
1005
+ GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3,
1006
+ (server, cq, tag));
1007
+
1008
+ /* lock, and gather up some stuff to do */
1009
+ gpr_mu_lock(&server->mu_global);
1010
+ grpc_cq_begin_op(cq, tag);
1011
+ if (server->shutdown_published) {
1012
+ grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL,
1013
+ gpr_malloc(sizeof(grpc_cq_completion)));
1014
+ gpr_mu_unlock(&server->mu_global);
1015
+ goto done;
1016
+ }
1017
+ server->shutdown_tags =
1018
+ gpr_realloc(server->shutdown_tags,
1019
+ sizeof(shutdown_tag) * (server->num_shutdown_tags + 1));
1020
+ sdt = &server->shutdown_tags[server->num_shutdown_tags++];
1021
+ sdt->tag = tag;
1022
+ sdt->cq = cq;
1023
+ if (gpr_atm_acq_load(&server->shutdown_flag)) {
1024
+ gpr_mu_unlock(&server->mu_global);
1025
+ goto done;
1026
+ }
1027
+
1028
+ server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
1029
+
1030
+ channel_broadcaster_init(server, &broadcaster);
1031
+
1032
+ gpr_atm_rel_store(&server->shutdown_flag, 1);
1033
+
1034
+ /* collect all unregistered then registered calls */
1035
+ gpr_mu_lock(&server->mu_call);
1036
+ kill_pending_work_locked(&exec_ctx, server);
1037
+ gpr_mu_unlock(&server->mu_call);
1038
+
1039
+ maybe_finish_shutdown(&exec_ctx, server);
1040
+ gpr_mu_unlock(&server->mu_global);
1041
+
1042
+ /* Shutdown listeners */
1043
+ for (l = server->listeners; l; l = l->next) {
1044
+ grpc_closure_init(&l->destroy_done, listener_destroy_done, server);
1045
+ l->destroy(&exec_ctx, server, l->arg, &l->destroy_done);
1046
+ }
1047
+
1048
+ channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0);
1049
+
1050
+ done:
1051
+ grpc_exec_ctx_finish(&exec_ctx);
1052
+ }
1053
+
1054
+ void grpc_server_cancel_all_calls(grpc_server *server) {
1055
+ channel_broadcaster broadcaster;
1056
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
1057
+
1058
+ GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server));
1059
+
1060
+ gpr_mu_lock(&server->mu_global);
1061
+ channel_broadcaster_init(server, &broadcaster);
1062
+ gpr_mu_unlock(&server->mu_global);
1063
+
1064
+ channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1);
1065
+ grpc_exec_ctx_finish(&exec_ctx);
1066
+ }
1067
+
1068
+ void grpc_server_destroy(grpc_server *server) {
1069
+ listener *l;
1070
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
1071
+
1072
+ GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server));
1073
+
1074
+ gpr_mu_lock(&server->mu_global);
1075
+ GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners);
1076
+ GPR_ASSERT(server->listeners_destroyed == num_listeners(server));
1077
+
1078
+ while (server->listeners) {
1079
+ l = server->listeners;
1080
+ server->listeners = l->next;
1081
+ gpr_free(l);
1082
+ }
1083
+
1084
+ gpr_mu_unlock(&server->mu_global);
1085
+
1086
+ server_unref(&exec_ctx, server);
1087
+ grpc_exec_ctx_finish(&exec_ctx);
1088
+ }
1089
+
1090
+ void grpc_server_add_listener(
1091
+ grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1092
+ void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1093
+ grpc_pollset **pollsets, size_t pollset_count),
1094
+ void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1095
+ grpc_closure *on_done)) {
1096
+ listener *l = gpr_malloc(sizeof(listener));
1097
+ l->arg = arg;
1098
+ l->start = start;
1099
+ l->destroy = destroy;
1100
+ l->next = server->listeners;
1101
+ server->listeners = l;
1102
+ }
1103
+
1104
+ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1105
+ grpc_server *server,
1106
+ requested_call *rc) {
1107
+ call_data *calld = NULL;
1108
+ request_matcher *rm = NULL;
1109
+ int request_id;
1110
+ if (gpr_atm_acq_load(&server->shutdown_flag)) {
1111
+ fail_call(exec_ctx, server, rc);
1112
+ return GRPC_CALL_OK;
1113
+ }
1114
+ request_id = gpr_stack_lockfree_pop(server->request_freelist);
1115
+ if (request_id == -1) {
1116
+ /* out of request ids: just fail this one */
1117
+ fail_call(exec_ctx, server, rc);
1118
+ return GRPC_CALL_OK;
1119
+ }
1120
+ switch (rc->type) {
1121
+ case BATCH_CALL:
1122
+ rm = &server->unregistered_request_matcher;
1123
+ break;
1124
+ case REGISTERED_CALL:
1125
+ rm = &rc->data.registered.registered_method->request_matcher;
1126
+ break;
1127
+ }
1128
+ server->requested_calls[request_id] = *rc;
1129
+ gpr_free(rc);
1130
+ if (gpr_stack_lockfree_push(rm->requests, request_id)) {
1131
+ /* this was the first queued request: we need to lock and start
1132
+ matching calls */
1133
+ gpr_mu_lock(&server->mu_call);
1134
+ while ((calld = rm->pending_head) != NULL) {
1135
+ request_id = gpr_stack_lockfree_pop(rm->requests);
1136
+ if (request_id == -1) break;
1137
+ rm->pending_head = calld->pending_next;
1138
+ gpr_mu_unlock(&server->mu_call);
1139
+ gpr_mu_lock(&calld->mu_state);
1140
+ if (calld->state == ZOMBIED) {
1141
+ gpr_mu_unlock(&calld->mu_state);
1142
+ grpc_closure_init(
1143
+ &calld->kill_zombie_closure, kill_zombie,
1144
+ grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
1145
+ grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
1146
+ } else {
1147
+ GPR_ASSERT(calld->state == PENDING);
1148
+ calld->state = ACTIVATED;
1149
+ gpr_mu_unlock(&calld->mu_state);
1150
+ begin_call(exec_ctx, server, calld,
1151
+ &server->requested_calls[request_id]);
1152
+ }
1153
+ gpr_mu_lock(&server->mu_call);
1154
+ }
1155
+ gpr_mu_unlock(&server->mu_call);
1156
+ }
1157
+ return GRPC_CALL_OK;
1158
+ }
1159
+
1160
+ grpc_call_error grpc_server_request_call(
1161
+ grpc_server *server, grpc_call **call, grpc_call_details *details,
1162
+ grpc_metadata_array *initial_metadata,
1163
+ grpc_completion_queue *cq_bound_to_call,
1164
+ grpc_completion_queue *cq_for_notification, void *tag) {
1165
+ grpc_call_error error;
1166
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
1167
+ requested_call *rc = gpr_malloc(sizeof(*rc));
1168
+ GRPC_API_TRACE(
1169
+ "grpc_server_request_call("
1170
+ "server=%p, call=%p, details=%p, initial_metadata=%p, "
1171
+ "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)",
1172
+ 7, (server, call, details, initial_metadata, cq_bound_to_call,
1173
+ cq_for_notification, tag));
1174
+ if (!grpc_cq_is_server_cq(cq_for_notification)) {
1175
+ gpr_free(rc);
1176
+ error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1177
+ goto done;
1178
+ }
1179
+ grpc_cq_begin_op(cq_for_notification, tag);
1180
+ details->reserved = NULL;
1181
+ rc->type = BATCH_CALL;
1182
+ rc->server = server;
1183
+ rc->tag = tag;
1184
+ rc->cq_bound_to_call = cq_bound_to_call;
1185
+ rc->cq_for_notification = cq_for_notification;
1186
+ rc->call = call;
1187
+ rc->data.batch.details = details;
1188
+ rc->initial_metadata = initial_metadata;
1189
+ error = queue_call_request(&exec_ctx, server, rc);
1190
+ done:
1191
+ grpc_exec_ctx_finish(&exec_ctx);
1192
+ return error;
1193
+ }
1194
+
1195
+ grpc_call_error grpc_server_request_registered_call(
1196
+ grpc_server *server, void *rmp, grpc_call **call, gpr_timespec *deadline,
1197
+ grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload,
1198
+ grpc_completion_queue *cq_bound_to_call,
1199
+ grpc_completion_queue *cq_for_notification, void *tag) {
1200
+ grpc_call_error error;
1201
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
1202
+ requested_call *rc = gpr_malloc(sizeof(*rc));
1203
+ registered_method *rm = rmp;
1204
+ GRPC_API_TRACE(
1205
+ "grpc_server_request_registered_call("
1206
+ "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, "
1207
+ "optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
1208
+ "tag=%p)",
1209
+ 9, (server, rmp, call, deadline, initial_metadata, optional_payload,
1210
+ cq_bound_to_call, cq_for_notification, tag));
1211
+ if (!grpc_cq_is_server_cq(cq_for_notification)) {
1212
+ gpr_free(rc);
1213
+ error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1214
+ goto done;
1215
+ }
1216
+ grpc_cq_begin_op(cq_for_notification, tag);
1217
+ rc->type = REGISTERED_CALL;
1218
+ rc->server = server;
1219
+ rc->tag = tag;
1220
+ rc->cq_bound_to_call = cq_bound_to_call;
1221
+ rc->cq_for_notification = cq_for_notification;
1222
+ rc->call = call;
1223
+ rc->data.registered.registered_method = rm;
1224
+ rc->data.registered.deadline = deadline;
1225
+ rc->initial_metadata = initial_metadata;
1226
+ rc->data.registered.optional_payload = optional_payload;
1227
+ error = queue_call_request(&exec_ctx, server, rc);
1228
+ done:
1229
+ grpc_exec_ctx_finish(&exec_ctx);
1230
+ return error;
1231
+ }
1232
+
1233
+ static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx,
1234
+ void *user_data, int success);
1235
+
1236
+ static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
1237
+ gpr_slice slice = value->slice;
1238
+ size_t len = GPR_SLICE_LENGTH(slice);
1239
+
1240
+ if (len + 1 > *capacity) {
1241
+ *capacity = GPR_MAX(len + 1, *capacity * 2);
1242
+ *dest = gpr_realloc(*dest, *capacity);
1243
+ }
1244
+ memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
1245
+ }
1246
+
1247
+ static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1248
+ call_data *calld, requested_call *rc) {
1249
+ grpc_op ops[1];
1250
+ grpc_op *op = ops;
1251
+
1252
+ memset(ops, 0, sizeof(ops));
1253
+
1254
+ /* called once initial metadata has been read by the call, but BEFORE
1255
+ the ioreq to fetch it out of the call has been executed.
1256
+ This means metadata related fields can be relied on in calld, but to
1257
+ fill in the metadata array passed by the client, we need to perform
1258
+ an ioreq op, that should complete immediately. */
1259
+
1260
+ grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
1261
+ grpc_closure_init(&rc->publish, publish_registered_or_batch, rc);
1262
+ *rc->call = calld->call;
1263
+ calld->cq_new = rc->cq_for_notification;
1264
+ GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
1265
+ switch (rc->type) {
1266
+ case BATCH_CALL:
1267
+ GPR_ASSERT(calld->host != NULL);
1268
+ GPR_ASSERT(calld->path != NULL);
1269
+ cpstr(&rc->data.batch.details->host,
1270
+ &rc->data.batch.details->host_capacity, calld->host);
1271
+ cpstr(&rc->data.batch.details->method,
1272
+ &rc->data.batch.details->method_capacity, calld->path);
1273
+ rc->data.batch.details->deadline = calld->deadline;
1274
+ break;
1275
+ case REGISTERED_CALL:
1276
+ *rc->data.registered.deadline = calld->deadline;
1277
+ if (rc->data.registered.optional_payload) {
1278
+ op->op = GRPC_OP_RECV_MESSAGE;
1279
+ op->data.recv_message = rc->data.registered.optional_payload;
1280
+ op++;
1281
+ }
1282
+ break;
1283
+ default:
1284
+ GPR_UNREACHABLE_CODE(return );
1285
+ }
1286
+
1287
+ GRPC_CALL_INTERNAL_REF(calld->call, "server");
1288
+ grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops,
1289
+ (size_t)(op - ops), &rc->publish);
1290
+ }
1291
+
1292
+ static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
1293
+ grpc_cq_completion *c) {
1294
+ requested_call *rc = req;
1295
+ grpc_server *server = rc->server;
1296
+
1297
+ if (rc >= server->requested_calls &&
1298
+ rc < server->requested_calls + server->max_requested_calls) {
1299
+ GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
1300
+ gpr_stack_lockfree_push(server->request_freelist,
1301
+ (int)(rc - server->requested_calls));
1302
+ } else {
1303
+ gpr_free(req);
1304
+ }
1305
+
1306
+ server_unref(exec_ctx, server);
1307
+ }
1308
+
1309
+ static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1310
+ requested_call *rc) {
1311
+ *rc->call = NULL;
1312
+ rc->initial_metadata->count = 0;
1313
+
1314
+ server_ref(server);
1315
+ grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
1316
+ done_request_event, rc, &rc->completion);
1317
+ }
1318
+
1319
+ static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc,
1320
+ int success) {
1321
+ requested_call *rc = prc;
1322
+ grpc_call *call = *rc->call;
1323
+ grpc_call_element *elem =
1324
+ grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
1325
+ call_data *calld = elem->call_data;
1326
+ channel_data *chand = elem->channel_data;
1327
+ server_ref(chand->server);
1328
+ grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event,
1329
+ rc, &rc->completion);
1330
+ GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server");
1331
+ }
1332
+
1333
+ const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
1334
+ return server->channel_args;
1335
+ }
1336
+
1337
+ int grpc_server_has_open_connections(grpc_server *server) {
1338
+ int r;
1339
+ gpr_mu_lock(&server->mu_global);
1340
+ r = server->root_channel_data.next != &server->root_channel_data;
1341
+ gpr_mu_unlock(&server->mu_global);
1342
+ return r;
1343
+ }