blob: 4b46f2b3c26360a9493d2ee2dbbcfb0f4be2fcb0 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Bogdan Drutuaff40662016-01-25 10:21:38 -08003 * Copyright 2015-2016, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * 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
Craig Tillerf96dfc32015-09-10 14:43:18 -070036#include <limits.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080037#include <stdlib.h>
38#include <string.h>
39
Craig Tiller6a006ce2015-07-13 16:25:40 -070040#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
Hongyu Chene09dc782015-08-21 11:28:33 -070045#include "src/core/census/grpc_filter.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080046#include "src/core/channel/channel_args.h"
47#include "src/core/channel/connected_channel.h"
ctiller18b49ab2014-12-09 14:39:16 -080048#include "src/core/iomgr/iomgr.h"
Craig Tiller6a006ce2015-07-13 16:25:40 -070049#include "src/core/support/stack_lockfree.h"
Craig Tiller485d7762015-01-23 12:54:05 -080050#include "src/core/support/string.h"
Masood Malekghassemi76c3d742015-08-19 18:22:53 -070051#include "src/core/surface/api_trace.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080052#include "src/core/surface/call.h"
53#include "src/core/surface/channel.h"
54#include "src/core/surface/completion_queue.h"
Craig Tiller60fd3612015-03-05 16:24:22 -080055#include "src/core/surface/init.h"
Craig Tillercce17ac2015-01-20 09:29:28 -080056#include "src/core/transport/metadata.h"
Craig Tillerebdef9d2015-11-19 17:09:49 -080057#include "src/core/transport/static_metadata.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080058
Craig Tillera82950e2015-09-22 12:33:20 -070059typedef struct listener {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080060 void *arg;
Craig Tillera82950e2015-09-22 12:33:20 -070061 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);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080065 struct listener *next;
Craig Tillerdfff1b82015-09-21 14:39:57 -070066 grpc_closure destroy_done;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080067} listener;
68
69typedef struct call_data call_data;
70typedef struct channel_data channel_data;
Craig Tiller24be0f72015-02-10 14:04:22 -080071typedef struct registered_method registered_method;
72
Craig Tillera82950e2015-09-22 12:33:20 -070073typedef struct {
Craig Tiller24be0f72015-02-10 14:04:22 -080074 call_data *next;
75 call_data *prev;
76} call_link;
77
Craig Tillera82950e2015-09-22 12:33:20 -070078typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type;
Craig Tiller24be0f72015-02-10 14:04:22 -080079
Craig Tillera82950e2015-09-22 12:33:20 -070080typedef struct requested_call {
Craig Tiller24be0f72015-02-10 14:04:22 -080081 requested_call_type type;
82 void *tag;
Craig Tiller6a006ce2015-07-13 16:25:40 -070083 grpc_server *server;
Craig Tillerf9e6adf2015-05-06 11:45:59 -070084 grpc_completion_queue *cq_bound_to_call;
85 grpc_completion_queue *cq_for_notification;
86 grpc_call **call;
Craig Tiller97fc6a32015-07-08 15:31:35 -070087 grpc_cq_completion completion;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -080088 grpc_metadata_array *initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -070089 union {
90 struct {
Craig Tiller24be0f72015-02-10 14:04:22 -080091 grpc_call_details *details;
Craig Tiller24be0f72015-02-10 14:04:22 -080092 } batch;
Craig Tillera82950e2015-09-22 12:33:20 -070093 struct {
Craig Tiller24be0f72015-02-10 14:04:22 -080094 registered_method *registered_method;
95 gpr_timespec *deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -080096 grpc_byte_buffer **optional_payload;
97 } registered;
98 } data;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -080099 grpc_closure publish;
Craig Tiller24be0f72015-02-10 14:04:22 -0800100} requested_call;
101
Craig Tillera82950e2015-09-22 12:33:20 -0700102typedef struct channel_registered_method {
Craig Tiller24be0f72015-02-10 14:04:22 -0800103 registered_method *server_registered_method;
Craig Tillerb2906862016-03-10 06:50:07 -0800104 uint32_t flags;
Craig Tiller24be0f72015-02-10 14:04:22 -0800105 grpc_mdstr *method;
106 grpc_mdstr *host;
107} channel_registered_method;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800108
Craig Tillera82950e2015-09-22 12:33:20 -0700109struct channel_data {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800110 grpc_server *server;
Craig Tillere039f032015-06-25 12:54:23 -0700111 grpc_connectivity_state connectivity_state;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800112 grpc_channel *channel;
113 /* linked list of all channels on a server */
114 channel_data *next;
115 channel_data *prev;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800116 channel_registered_method *registered_methods;
Craig Tiller7536af02015-12-22 13:49:30 -0800117 uint32_t registered_method_slots;
118 uint32_t registered_method_max_probes;
Craig Tiller33825112015-09-18 07:44:19 -0700119 grpc_closure finish_destroy_channel_closure;
120 grpc_closure channel_connectivity_changed;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800121};
122
Craig Tillera82950e2015-09-22 12:33:20 -0700123typedef struct shutdown_tag {
Craig Tillerbce999f2015-05-27 09:55:51 -0700124 void *tag;
125 grpc_completion_queue *cq;
Craig Tiller97fc6a32015-07-08 15:31:35 -0700126 grpc_cq_completion completion;
Craig Tillerbce999f2015-05-27 09:55:51 -0700127} shutdown_tag;
128
Craig Tillera82950e2015-09-22 12:33:20 -0700129typedef enum {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800130 /* waiting for metadata */
131 NOT_STARTED,
132 /* inital metadata read, not flow controlled in yet */
133 PENDING,
134 /* flow controlled in, on completion queue */
135 ACTIVATED,
136 /* cancelled before being queued */
137 ZOMBIED
138} call_state;
139
Craig Tiller729b35a2015-07-13 12:36:47 -0700140typedef struct request_matcher request_matcher;
141
Craig Tillera82950e2015-09-22 12:33:20 -0700142struct call_data {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800143 grpc_call *call;
144
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700145 /** protects state */
146 gpr_mu mu_state;
147 /** the current state of a call - see call_state */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800148 call_state state;
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700149
Craig Tillercce17ac2015-01-20 09:29:28 -0800150 grpc_mdstr *path;
151 grpc_mdstr *host;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700152 gpr_timespec deadline;
Craig Tillercce17ac2015-01-20 09:29:28 -0800153
Craig Tiller20bc56d2015-02-12 09:02:56 -0800154 grpc_completion_queue *cq_new;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800155
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800156 grpc_metadata_batch *recv_initial_metadata;
Craig Tiller4d40ba32016-03-09 17:48:40 -0800157 bool recv_idempotent_request;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800158 grpc_metadata_array initial_metadata;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700159
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800160 grpc_closure got_initial_metadata;
161 grpc_closure server_on_recv_initial_metadata;
Craig Tiller33825112015-09-18 07:44:19 -0700162 grpc_closure kill_zombie_closure;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800163 grpc_closure *on_done_recv_initial_metadata;
David Garcia Quintas284488b2015-05-28 16:27:39 -0700164
Craig Tiller729b35a2015-07-13 12:36:47 -0700165 call_data *pending_next;
166};
167
Craig Tillera82950e2015-09-22 12:33:20 -0700168struct request_matcher {
Craig Tiller729b35a2015-07-13 12:36:47 -0700169 call_data *pending_head;
170 call_data *pending_tail;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700171 gpr_stack_lockfree *requests;
Craig Tiller729b35a2015-07-13 12:36:47 -0700172};
173
Craig Tillera82950e2015-09-22 12:33:20 -0700174struct registered_method {
Craig Tiller729b35a2015-07-13 12:36:47 -0700175 char *method;
176 char *host;
Craig Tillerb2906862016-03-10 06:50:07 -0800177 uint32_t flags;
Craig Tiller729b35a2015-07-13 12:36:47 -0700178 request_matcher request_matcher;
179 registered_method *next;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800180};
181
Craig Tillera82950e2015-09-22 12:33:20 -0700182typedef struct {
Craig Tillerff3ae682015-06-29 17:44:04 -0700183 grpc_channel **channels;
184 size_t num_channels;
185} channel_broadcaster;
186
Craig Tillera82950e2015-09-22 12:33:20 -0700187struct grpc_server {
Craig Tiller729b35a2015-07-13 12:36:47 -0700188 size_t channel_filter_count;
Craig Tiller565b18b2015-09-23 10:09:42 -0700189 grpc_channel_filter const **channel_filters;
Craig Tiller729b35a2015-07-13 12:36:47 -0700190 grpc_channel_args *channel_args;
191
192 grpc_completion_queue **cqs;
193 grpc_pollset **pollsets;
194 size_t cq_count;
195
196 /* The two following mutexes control access to server-state
197 mu_global controls access to non-call-related state (e.g., channel state)
198 mu_call controls access to call-related state (e.g., the call lists)
199
200 If they are ever required to be nested, you must lock mu_global
201 before mu_call. This is currently used in shutdown processing
202 (grpc_server_shutdown_and_notify and maybe_finish_shutdown) */
Craig Tillera82950e2015-09-22 12:33:20 -0700203 gpr_mu mu_global; /* mutex for server and channel state */
204 gpr_mu mu_call; /* mutex for call-specific state */
Craig Tiller729b35a2015-07-13 12:36:47 -0700205
206 registered_method *registered_methods;
207 request_matcher unregistered_request_matcher;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700208 /** free list of available requested_calls indices */
209 gpr_stack_lockfree *request_freelist;
210 /** requested call backing data */
211 requested_call *requested_calls;
Craig Tiller32ca48c2015-09-10 11:47:15 -0700212 size_t max_requested_calls;
Craig Tiller729b35a2015-07-13 12:36:47 -0700213
Craig Tiller6a006ce2015-07-13 16:25:40 -0700214 gpr_atm shutdown_flag;
Craig Tiller7536af02015-12-22 13:49:30 -0800215 uint8_t shutdown_published;
Craig Tiller729b35a2015-07-13 12:36:47 -0700216 size_t num_shutdown_tags;
217 shutdown_tag *shutdown_tags;
218
219 channel_data root_channel_data;
220
221 listener *listeners;
222 int listeners_destroyed;
223 gpr_refcount internal_refcount;
224
225 /** when did we print the last shutdown progress message */
226 gpr_timespec last_shutdown_message_time;
227};
228
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800229#define SERVER_FROM_CALL_ELEM(elem) \
230 (((channel_data *)(elem)->channel_data)->server)
231
Craig Tillera82950e2015-09-22 12:33:20 -0700232static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
233 call_data *calld, requested_call *rc);
234static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
235 requested_call *rc);
Vijay Pai8931cdd2015-06-17 12:42:17 -0700236/* Before calling maybe_finish_shutdown, we must hold mu_global and not
237 hold mu_call */
Craig Tillera82950e2015-09-22 12:33:20 -0700238static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server);
Craig Tiller24be0f72015-02-10 14:04:22 -0800239
Craig Tiller729b35a2015-07-13 12:36:47 -0700240/*
241 * channel broadcaster
242 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700243
244/* assumes server locked */
Craig Tillera82950e2015-09-22 12:33:20 -0700245static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700246 channel_data *c;
247 size_t count = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700248 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
249 count++;
250 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700251 cb->num_channels = count;
Craig Tillera82950e2015-09-22 12:33:20 -0700252 cb->channels = gpr_malloc(sizeof(*cb->channels) * cb->num_channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700253 count = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700254 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
255 cb->channels[count++] = c->channel;
256 GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast");
257 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700258}
259
Craig Tillera82950e2015-09-22 12:33:20 -0700260struct shutdown_cleanup_args {
Craig Tiller33825112015-09-18 07:44:19 -0700261 grpc_closure closure;
Craig Tillerff3ae682015-06-29 17:44:04 -0700262 gpr_slice slice;
263};
264
Craig Tillera82950e2015-09-22 12:33:20 -0700265static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
Craig Tiller6c396862016-01-28 13:53:40 -0800266 bool iomgr_status_ignored) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700267 struct shutdown_cleanup_args *a = arg;
Craig Tillera82950e2015-09-22 12:33:20 -0700268 gpr_slice_unref(a->slice);
269 gpr_free(a);
Craig Tillerff3ae682015-06-29 17:44:04 -0700270}
271
Craig Tillera82950e2015-09-22 12:33:20 -0700272static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
273 int send_goaway, int send_disconnect) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700274 grpc_transport_op op;
275 struct shutdown_cleanup_args *sc;
276 grpc_channel_element *elem;
277
Craig Tillera82950e2015-09-22 12:33:20 -0700278 memset(&op, 0, sizeof(op));
Craig Tillerff3ae682015-06-29 17:44:04 -0700279 op.send_goaway = send_goaway;
Craig Tillera82950e2015-09-22 12:33:20 -0700280 sc = gpr_malloc(sizeof(*sc));
281 sc->slice = gpr_slice_from_copied_string("Server shutdown");
Craig Tillerff3ae682015-06-29 17:44:04 -0700282 op.goaway_message = &sc->slice;
283 op.goaway_status = GRPC_STATUS_OK;
284 op.disconnect = send_disconnect;
Craig Tillera82950e2015-09-22 12:33:20 -0700285 grpc_closure_init(&sc->closure, shutdown_cleanup, sc);
Craig Tillerff3ae682015-06-29 17:44:04 -0700286 op.on_consumed = &sc->closure;
287
Craig Tillera82950e2015-09-22 12:33:20 -0700288 elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
289 elem->filter->start_transport_op(exec_ctx, elem, &op);
Craig Tillerff3ae682015-06-29 17:44:04 -0700290}
291
Craig Tillera82950e2015-09-22 12:33:20 -0700292static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx,
293 channel_broadcaster *cb,
294 int send_goaway,
295 int force_disconnect) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700296 size_t i;
297
Craig Tillera82950e2015-09-22 12:33:20 -0700298 for (i = 0; i < cb->num_channels; i++) {
299 send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect);
300 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast");
301 }
302 gpr_free(cb->channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700303}
304
Craig Tiller729b35a2015-07-13 12:36:47 -0700305/*
306 * request_matcher
307 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700308
Craig Tiller8dc09712015-09-24 13:58:16 -0700309static void request_matcher_init(request_matcher *rm, size_t entries) {
Craig Tillerb9d35962015-09-11 13:31:16 -0700310 memset(rm, 0, sizeof(*rm));
311 rm->requests = gpr_stack_lockfree_create(entries);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800312}
313
Craig Tillerb9d35962015-09-11 13:31:16 -0700314static void request_matcher_destroy(request_matcher *rm) {
315 GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests) == -1);
316 gpr_stack_lockfree_destroy(rm->requests);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800317}
318
Craig Tiller6c396862016-01-28 13:53:40 -0800319static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, bool success) {
Craig Tillera82950e2015-09-22 12:33:20 -0700320 grpc_call_destroy(grpc_call_from_top_element(elem));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800321}
322
Craig Tiller8dc09712015-09-24 13:58:16 -0700323static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx,
324 request_matcher *rm) {
Craig Tillerb9d35962015-09-11 13:31:16 -0700325 while (rm->pending_head) {
326 call_data *calld = rm->pending_head;
327 rm->pending_head = calld->pending_next;
Craig Tillera82950e2015-09-22 12:33:20 -0700328 gpr_mu_lock(&calld->mu_state);
329 calld->state = ZOMBIED;
330 gpr_mu_unlock(&calld->mu_state);
331 grpc_closure_init(
332 &calld->kill_zombie_closure, kill_zombie,
333 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
Craig Tiller6c396862016-01-28 13:53:40 -0800334 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillera82950e2015-09-22 12:33:20 -0700335 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800336}
337
Craig Tillera82950e2015-09-22 12:33:20 -0700338static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx,
339 grpc_server *server,
340 request_matcher *rm) {
Craig Tiller1191e212015-07-30 14:49:02 -0700341 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -0700342 while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) {
343 fail_call(exec_ctx, server, &server->requested_calls[request_id]);
344 }
Craig Tiller1191e212015-07-30 14:49:02 -0700345}
346
Craig Tiller729b35a2015-07-13 12:36:47 -0700347/*
348 * server proper
349 */
350
Craig Tillera82950e2015-09-22 12:33:20 -0700351static void server_ref(grpc_server *server) {
352 gpr_ref(&server->internal_refcount);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800353}
354
Craig Tillera82950e2015-09-22 12:33:20 -0700355static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800356 registered_method *rm;
Craig Tiller89504612015-04-27 11:48:46 -0700357 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700358 grpc_channel_args_destroy(server->channel_args);
359 gpr_mu_destroy(&server->mu_global);
360 gpr_mu_destroy(&server->mu_call);
Craig Tiller565b18b2015-09-23 10:09:42 -0700361 gpr_free((void *)server->channel_filters);
Craig Tillera82950e2015-09-22 12:33:20 -0700362 while ((rm = server->registered_methods) != NULL) {
363 server->registered_methods = rm->next;
364 request_matcher_destroy(&rm->request_matcher);
365 gpr_free(rm->method);
366 gpr_free(rm->host);
367 gpr_free(rm);
368 }
369 for (i = 0; i < server->cq_count; i++) {
370 GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server");
371 }
372 request_matcher_destroy(&server->unregistered_request_matcher);
373 gpr_stack_lockfree_destroy(server->request_freelist);
374 gpr_free(server->cqs);
375 gpr_free(server->pollsets);
376 gpr_free(server->shutdown_tags);
377 gpr_free(server->requested_calls);
378 gpr_free(server);
Craig Tilleree945e82015-05-26 16:15:34 -0700379}
380
Craig Tillera82950e2015-09-22 12:33:20 -0700381static void server_unref(grpc_exec_ctx *exec_ctx, grpc_server *server) {
382 if (gpr_unref(&server->internal_refcount)) {
383 server_delete(exec_ctx, server);
384 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800385}
386
Craig Tillera82950e2015-09-22 12:33:20 -0700387static int is_channel_orphaned(channel_data *chand) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800388 return chand->next == chand;
389}
390
Craig Tillera82950e2015-09-22 12:33:20 -0700391static void orphan_channel(channel_data *chand) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800392 chand->next->prev = chand->prev;
393 chand->prev->next = chand->next;
394 chand->next = chand->prev = chand;
395}
396
Craig Tillera82950e2015-09-22 12:33:20 -0700397static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd,
Craig Tiller6c396862016-01-28 13:53:40 -0800398 bool success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800399 channel_data *chand = cd;
400 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700401 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server");
402 server_unref(exec_ctx, server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800403}
404
Craig Tillera82950e2015-09-22 12:33:20 -0700405static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) {
406 if (is_channel_orphaned(chand)) return;
407 GPR_ASSERT(chand->server != NULL);
408 orphan_channel(chand);
409 server_ref(chand->server);
410 maybe_finish_shutdown(exec_ctx, chand->server);
David Garcia Quintas284488b2015-05-28 16:27:39 -0700411 chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
412 chand->finish_destroy_channel_closure.cb_arg = chand;
Craig Tillerd7f12e32016-03-03 10:08:31 -0800413
414 grpc_transport_op op;
415 memset(&op, 0, sizeof(op));
416 op.set_accept_stream = true;
417 op.on_consumed = &chand->finish_destroy_channel_closure;
418 grpc_channel_next_op(exec_ctx,
419 grpc_channel_stack_element(
420 grpc_channel_get_channel_stack(chand->channel), 0),
421 &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800422}
423
Craig Tillera82950e2015-09-22 12:33:20 -0700424static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server,
Craig Tiller8dc09712015-09-24 13:58:16 -0700425 grpc_call_element *elem, request_matcher *rm) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800426 call_data *calld = elem->call_data;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700427 int request_id;
428
Craig Tillera82950e2015-09-22 12:33:20 -0700429 if (gpr_atm_acq_load(&server->shutdown_flag)) {
430 gpr_mu_lock(&calld->mu_state);
431 calld->state = ZOMBIED;
432 gpr_mu_unlock(&calld->mu_state);
433 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller6c396862016-01-28 13:53:40 -0800434 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillera82950e2015-09-22 12:33:20 -0700435 return;
436 }
Craig Tiller45724b32015-09-22 10:42:19 -0700437
Craig Tillerb9d35962015-09-11 13:31:16 -0700438 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -0700439 if (request_id == -1) {
440 gpr_mu_lock(&server->mu_call);
441 gpr_mu_lock(&calld->mu_state);
442 calld->state = PENDING;
443 gpr_mu_unlock(&calld->mu_state);
Craig Tillerb9d35962015-09-11 13:31:16 -0700444 if (rm->pending_head == NULL) {
445 rm->pending_tail = rm->pending_head = calld;
Craig Tillera82950e2015-09-22 12:33:20 -0700446 } else {
Craig Tillerb9d35962015-09-11 13:31:16 -0700447 rm->pending_tail->pending_next = calld;
448 rm->pending_tail = calld;
Craig Tiller45724b32015-09-22 10:42:19 -0700449 }
Craig Tillera82950e2015-09-22 12:33:20 -0700450 calld->pending_next = NULL;
451 gpr_mu_unlock(&server->mu_call);
452 } else {
453 gpr_mu_lock(&calld->mu_state);
454 calld->state = ACTIVATED;
455 gpr_mu_unlock(&calld->mu_state);
456 begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
457 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800458}
459
Craig Tillera82950e2015-09-22 12:33:20 -0700460static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800461 channel_data *chand = elem->channel_data;
462 call_data *calld = elem->call_data;
463 grpc_server *server = chand->server;
Craig Tiller7536af02015-12-22 13:49:30 -0800464 uint32_t i;
465 uint32_t hash;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800466 channel_registered_method *rm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800467
Craig Tillera82950e2015-09-22 12:33:20 -0700468 if (chand->registered_methods && calld->path && calld->host) {
469 /* TODO(ctiller): unify these two searches */
470 /* check for an exact match with host */
471 hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
472 for (i = 0; i <= chand->registered_method_max_probes; i++) {
473 rm = &chand->registered_methods[(hash + i) %
474 chand->registered_method_slots];
475 if (!rm) break;
476 if (rm->host != calld->host) continue;
477 if (rm->method != calld->path) continue;
Craig Tillerb2906862016-03-10 06:50:07 -0800478 if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
479 !calld->recv_idempotent_request)
480 continue;
Craig Tillera82950e2015-09-22 12:33:20 -0700481 finish_start_new_rpc(exec_ctx, server, elem,
482 &rm->server_registered_method->request_matcher);
483 return;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800484 }
Craig Tillera82950e2015-09-22 12:33:20 -0700485 /* check for a wildcard method definition (no host set) */
486 hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
487 for (i = 0; i <= chand->registered_method_max_probes; i++) {
488 rm = &chand->registered_methods[(hash + i) %
489 chand->registered_method_slots];
490 if (!rm) break;
491 if (rm->host != NULL) continue;
492 if (rm->method != calld->path) continue;
Craig Tillerb2906862016-03-10 06:50:07 -0800493 if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
494 !calld->recv_idempotent_request)
495 continue;
Craig Tillera82950e2015-09-22 12:33:20 -0700496 finish_start_new_rpc(exec_ctx, server, elem,
497 &rm->server_registered_method->request_matcher);
498 return;
499 }
500 }
501 finish_start_new_rpc(exec_ctx, server, elem,
502 &server->unregistered_request_matcher);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800503}
504
Craig Tillera82950e2015-09-22 12:33:20 -0700505static int num_listeners(grpc_server *server) {
Craig Tilleree945e82015-05-26 16:15:34 -0700506 listener *l;
507 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700508 for (l = server->listeners; l; l = l->next) {
509 n++;
510 }
Craig Tilleree945e82015-05-26 16:15:34 -0700511 return n;
512}
513
Craig Tillera82950e2015-09-22 12:33:20 -0700514static void done_shutdown_event(grpc_exec_ctx *exec_ctx, void *server,
515 grpc_cq_completion *completion) {
516 server_unref(exec_ctx, server);
Craig Tiller97fc6a32015-07-08 15:31:35 -0700517}
518
Craig Tillera82950e2015-09-22 12:33:20 -0700519static int num_channels(grpc_server *server) {
Craig Tillerab54f792015-07-08 08:34:20 -0700520 channel_data *chand;
521 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700522 for (chand = server->root_channel_data.next;
523 chand != &server->root_channel_data; chand = chand->next) {
524 n++;
525 }
Craig Tillerab54f792015-07-08 08:34:20 -0700526 return n;
527}
528
Craig Tillera82950e2015-09-22 12:33:20 -0700529static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx,
530 grpc_server *server) {
Craig Tiller1191e212015-07-30 14:49:02 -0700531 registered_method *rm;
Craig Tillera82950e2015-09-22 12:33:20 -0700532 request_matcher_kill_requests(exec_ctx, server,
533 &server->unregistered_request_matcher);
534 request_matcher_zombify_all_pending_calls(
535 exec_ctx, &server->unregistered_request_matcher);
536 for (rm = server->registered_methods; rm; rm = rm->next) {
537 request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher);
538 request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
539 }
Craig Tillerdc627722015-05-26 15:27:02 -0700540}
541
Craig Tillera82950e2015-09-22 12:33:20 -0700542static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
543 grpc_server *server) {
Craig Tiller45724b32015-09-22 10:42:19 -0700544 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700545 if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) {
546 return;
547 }
Craig Tiller45724b32015-09-22 10:42:19 -0700548
Craig Tillera82950e2015-09-22 12:33:20 -0700549 kill_pending_work_locked(exec_ctx, server);
Craig Tiller45724b32015-09-22 10:42:19 -0700550
Craig Tillera82950e2015-09-22 12:33:20 -0700551 if (server->root_channel_data.next != &server->root_channel_data ||
552 server->listeners_destroyed < num_listeners(server)) {
553 if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
554 server->last_shutdown_message_time),
555 gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
556 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
557 gpr_log(GPR_DEBUG,
558 "Waiting for %d channels and %d/%d listeners to be destroyed"
559 " before shutting down server",
560 num_channels(server),
561 num_listeners(server) - server->listeners_destroyed,
562 num_listeners(server));
Craig Tiller45724b32015-09-22 10:42:19 -0700563 }
Craig Tillera82950e2015-09-22 12:33:20 -0700564 return;
565 }
Craig Tiller45724b32015-09-22 10:42:19 -0700566 server->shutdown_published = 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700567 for (i = 0; i < server->num_shutdown_tags; i++) {
568 server_ref(server);
569 grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq,
570 server->shutdown_tags[i].tag, 1, done_shutdown_event, server,
571 &server->shutdown_tags[i].completion);
572 }
Craig Tiller45724b32015-09-22 10:42:19 -0700573}
574
Craig Tillera82950e2015-09-22 12:33:20 -0700575static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
Craig Tiller6902ad22015-04-16 08:01:49 -0700576 grpc_call_element *elem = user_data;
Craig Tillercce17ac2015-01-20 09:29:28 -0800577 call_data *calld = elem->call_data;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800578 if (md->key == GRPC_MDSTR_PATH) {
Craig Tillera82950e2015-09-22 12:33:20 -0700579 calld->path = GRPC_MDSTR_REF(md->value);
580 return NULL;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800581 } else if (md->key == GRPC_MDSTR_AUTHORITY) {
Craig Tillera82950e2015-09-22 12:33:20 -0700582 calld->host = GRPC_MDSTR_REF(md->value);
583 return NULL;
584 }
Craig Tiller6902ad22015-04-16 08:01:49 -0700585 return md;
586}
587
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800588static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
Craig Tiller6c396862016-01-28 13:53:40 -0800589 bool success) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700590 grpc_call_element *elem = ptr;
Craig Tiller6902ad22015-04-16 08:01:49 -0700591 call_data *calld = elem->call_data;
Craig Tiller94329d02015-07-23 09:52:11 -0700592 gpr_timespec op_deadline;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700593
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800594 grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
595 op_deadline = calld->recv_initial_metadata->deadline;
596 if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
597 calld->deadline = op_deadline;
598 }
599 if (calld->host && calld->path) {
600 /* do nothing */
601 } else {
602 success = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700603 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700604
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800605 calld->on_done_recv_initial_metadata->cb(
606 exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success);
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700607}
608
Craig Tillera82950e2015-09-22 12:33:20 -0700609static void server_mutate_op(grpc_call_element *elem,
610 grpc_transport_stream_op *op) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700611 call_data *calld = elem->call_data;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700612
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800613 if (op->recv_initial_metadata != NULL) {
Craig Tiller4d40ba32016-03-09 17:48:40 -0800614 GPR_ASSERT(op->recv_idempotent_request == NULL);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800615 calld->recv_initial_metadata = op->recv_initial_metadata;
Craig Tillera44cbfc2016-02-03 16:02:49 -0800616 calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
617 op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata;
Craig Tiller4d40ba32016-03-09 17:48:40 -0800618 op->recv_idempotent_request = &calld->recv_idempotent_request;
Craig Tillera82950e2015-09-22 12:33:20 -0700619 }
Craig Tiller50d9db52015-04-23 10:52:14 -0700620}
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700621
Craig Tillera82950e2015-09-22 12:33:20 -0700622static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
623 grpc_call_element *elem,
624 grpc_transport_stream_op *op) {
625 GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
626 server_mutate_op(elem, op);
627 grpc_call_next_op(exec_ctx, elem, op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800628}
629
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800630static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
Craig Tiller6c396862016-01-28 13:53:40 -0800631 bool success) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800632 grpc_call_element *elem = ptr;
633 call_data *calld = elem->call_data;
634 if (success) {
635 start_new_rpc(exec_ctx, elem);
636 } else {
637 gpr_mu_lock(&calld->mu_state);
638 if (calld->state == NOT_STARTED) {
639 calld->state = ZOMBIED;
640 gpr_mu_unlock(&calld->mu_state);
641 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller6c396862016-01-28 13:53:40 -0800642 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800643 } else if (calld->state == PENDING) {
644 calld->state = ZOMBIED;
645 gpr_mu_unlock(&calld->mu_state);
646 /* zombied call will be destroyed when it's removed from the pending
647 queue... later */
648 } else {
649 gpr_mu_unlock(&calld->mu_state);
650 }
651 }
652}
653
654static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
655 grpc_transport *transport,
Craig Tillera82950e2015-09-22 12:33:20 -0700656 const void *transport_server_data) {
Craig Tillere039f032015-06-25 12:54:23 -0700657 channel_data *chand = cd;
658 /* create a call */
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800659 grpc_call *call =
660 grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data,
661 NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
662 grpc_call_element *elem =
663 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
664 call_data *calld = elem->call_data;
665 grpc_op op;
666 memset(&op, 0, sizeof(op));
667 op.op = GRPC_OP_RECV_INITIAL_METADATA;
668 op.data.recv_initial_metadata = &calld->initial_metadata;
669 grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem);
670 grpc_call_start_batch_and_execute(exec_ctx, call, &op, 1,
671 &calld->got_initial_metadata);
Craig Tillere039f032015-06-25 12:54:23 -0700672}
673
Craig Tillera82950e2015-09-22 12:33:20 -0700674static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd,
Craig Tiller6c396862016-01-28 13:53:40 -0800675 bool iomgr_status_ignored) {
Craig Tillere039f032015-06-25 12:54:23 -0700676 channel_data *chand = cd;
677 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700678 if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
679 grpc_transport_op op;
680 memset(&op, 0, sizeof(op));
681 op.on_connectivity_state_change = &chand->channel_connectivity_changed,
682 op.connectivity_state = &chand->connectivity_state;
683 grpc_channel_next_op(exec_ctx,
684 grpc_channel_stack_element(
685 grpc_channel_get_channel_stack(chand->channel), 0),
686 &op);
687 } else {
688 gpr_mu_lock(&server->mu_global);
689 destroy_channel(exec_ctx, chand);
690 gpr_mu_unlock(&server->mu_global);
691 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity");
692 }
Craig Tillere039f032015-06-25 12:54:23 -0700693}
694
Craig Tillera82950e2015-09-22 12:33:20 -0700695static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800696 grpc_call_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800697 call_data *calld = elem->call_data;
698 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700699 memset(calld, 0, sizeof(call_data));
700 calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
701 calld->call = grpc_call_from_top_element(elem);
702 gpr_mu_init(&calld->mu_state);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800703
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800704 grpc_closure_init(&calld->server_on_recv_initial_metadata,
705 server_on_recv_initial_metadata, elem);
Craig Tiller1e6facb2015-06-11 22:47:11 -0700706
Craig Tillera82950e2015-09-22 12:33:20 -0700707 server_ref(chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800708}
709
Craig Tillera82950e2015-09-22 12:33:20 -0700710static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
711 grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800712 channel_data *chand = elem->channel_data;
Craig Tillerdb7db992015-01-29 11:19:01 -0800713 call_data *calld = elem->call_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800714
Craig Tillera82950e2015-09-22 12:33:20 -0700715 GPR_ASSERT(calld->state != PENDING);
Craig Tiller092d8d12015-07-04 22:35:00 -0700716
Craig Tillera82950e2015-09-22 12:33:20 -0700717 if (calld->host) {
718 GRPC_MDSTR_UNREF(calld->host);
719 }
720 if (calld->path) {
721 GRPC_MDSTR_UNREF(calld->path);
722 }
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800723 grpc_metadata_array_destroy(&calld->initial_metadata);
Craig Tiller4df31a62015-01-30 09:44:31 -0800724
Craig Tillera82950e2015-09-22 12:33:20 -0700725 gpr_mu_destroy(&calld->mu_state);
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700726
Craig Tillera82950e2015-09-22 12:33:20 -0700727 server_unref(exec_ctx, chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800728}
729
Craig Tillera82950e2015-09-22 12:33:20 -0700730static void init_channel_elem(grpc_exec_ctx *exec_ctx,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800731 grpc_channel_element *elem,
732 grpc_channel_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800733 channel_data *chand = elem->channel_data;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800734 GPR_ASSERT(args->is_first);
735 GPR_ASSERT(!args->is_last);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800736 chand->server = NULL;
737 chand->channel = NULL;
738 chand->next = chand->prev = chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800739 chand->registered_methods = NULL;
Craig Tillere039f032015-06-25 12:54:23 -0700740 chand->connectivity_state = GRPC_CHANNEL_IDLE;
Craig Tillera82950e2015-09-22 12:33:20 -0700741 grpc_closure_init(&chand->channel_connectivity_changed,
742 channel_connectivity_changed, chand);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800743}
744
Craig Tillera82950e2015-09-22 12:33:20 -0700745static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
746 grpc_channel_element *elem) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800747 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800748 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700749 if (chand->registered_methods) {
750 for (i = 0; i < chand->registered_method_slots; i++) {
751 if (chand->registered_methods[i].method) {
752 GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
753 }
754 if (chand->registered_methods[i].host) {
755 GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
756 }
Craig Tillerec3257c2015-02-12 15:59:43 -0800757 }
Craig Tillera82950e2015-09-22 12:33:20 -0700758 gpr_free(chand->registered_methods);
759 }
760 if (chand->server) {
761 gpr_mu_lock(&chand->server->mu_global);
762 chand->next->prev = chand->prev;
763 chand->prev->next = chand->next;
764 chand->next = chand->prev = chand;
765 maybe_finish_shutdown(exec_ctx, chand->server);
766 gpr_mu_unlock(&chand->server->mu_global);
Craig Tillera82950e2015-09-22 12:33:20 -0700767 server_unref(exec_ctx, chand->server);
768 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800769}
770
771static const grpc_channel_filter server_surface_filter = {
Craig Tiller5987c702016-03-09 16:55:23 -0800772 server_start_transport_stream_op,
773 grpc_channel_next_op,
774 sizeof(call_data),
775 init_call_elem,
776 grpc_call_stack_ignore_set_pollset,
777 destroy_call_elem,
778 sizeof(channel_data),
779 init_channel_elem,
780 destroy_channel_elem,
781 grpc_call_next_get_peer,
782 "server",
Craig Tiller9f28ac22015-01-27 17:01:29 -0800783};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800784
Craig Tillera82950e2015-09-22 12:33:20 -0700785void grpc_server_register_completion_queue(grpc_server *server,
786 grpc_completion_queue *cq,
787 void *reserved) {
Craig Tiller20bc56d2015-02-12 09:02:56 -0800788 size_t i, n;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700789 GRPC_API_TRACE(
790 "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
791 (server, cq, reserved));
Craig Tillera82950e2015-09-22 12:33:20 -0700792 GPR_ASSERT(!reserved);
793 for (i = 0; i < server->cq_count; i++) {
794 if (server->cqs[i] == cq) return;
795 }
796 GRPC_CQ_INTERNAL_REF(cq, "server");
797 grpc_cq_mark_server_cq(cq);
Craig Tiller20bc56d2015-02-12 09:02:56 -0800798 n = server->cq_count++;
Craig Tillera82950e2015-09-22 12:33:20 -0700799 server->cqs = gpr_realloc(server->cqs,
800 server->cq_count * sizeof(grpc_completion_queue *));
Craig Tiller20bc56d2015-02-12 09:02:56 -0800801 server->cqs[n] = cq;
802}
803
Craig Tillera82950e2015-09-22 12:33:20 -0700804grpc_server *grpc_server_create_from_filters(
805 const grpc_channel_filter **filters, size_t filter_count,
806 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800807 size_t i;
Bogdan Drutu441499a2016-01-26 19:16:04 -0800808 int census_enabled = grpc_channel_args_is_census_enabled(args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800809
Craig Tillera82950e2015-09-22 12:33:20 -0700810 grpc_server *server = gpr_malloc(sizeof(grpc_server));
Craig Tiller60fd3612015-03-05 16:24:22 -0800811
Craig Tillera82950e2015-09-22 12:33:20 -0700812 GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
Craig Tiller60fd3612015-03-05 16:24:22 -0800813
Craig Tillera82950e2015-09-22 12:33:20 -0700814 memset(server, 0, sizeof(grpc_server));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800815
Craig Tillera82950e2015-09-22 12:33:20 -0700816 gpr_mu_init(&server->mu_global);
817 gpr_mu_init(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800818
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800819 /* decremented by grpc_server_destroy */
Craig Tillera82950e2015-09-22 12:33:20 -0700820 gpr_ref_init(&server->internal_refcount, 1);
821 server->root_channel_data.next = server->root_channel_data.prev =
822 &server->root_channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800823
Craig Tiller6a006ce2015-07-13 16:25:40 -0700824 /* TODO(ctiller): expose a channel_arg for this */
825 server->max_requested_calls = 32768;
Craig Tillera82950e2015-09-22 12:33:20 -0700826 server->request_freelist =
827 gpr_stack_lockfree_create(server->max_requested_calls);
828 for (i = 0; i < (size_t)server->max_requested_calls; i++) {
829 gpr_stack_lockfree_push(server->request_freelist, (int)i);
830 }
831 request_matcher_init(&server->unregistered_request_matcher,
832 server->max_requested_calls);
833 server->requested_calls = gpr_malloc(server->max_requested_calls *
834 sizeof(*server->requested_calls));
Craig Tiller729b35a2015-07-13 12:36:47 -0700835
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800836 /* Server filter stack is:
837
838 server_surface_filter - for making surface API calls
839 grpc_server_census_filter (optional) - for stats collection and tracing
840 {passed in filter stack}
841 grpc_connected_channel_filter - for interfacing with transports */
Bogdan Drutu441499a2016-01-26 19:16:04 -0800842 server->channel_filter_count = filter_count + 1u + (census_enabled ? 1u : 0u);
Craig Tillera82950e2015-09-22 12:33:20 -0700843 server->channel_filters =
844 gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800845 server->channel_filters[0] = &server_surface_filter;
Bogdan Drutu441499a2016-01-26 19:16:04 -0800846 if (census_enabled) {
Craig Tillera82950e2015-09-22 12:33:20 -0700847 server->channel_filters[1] = &grpc_server_census_filter;
848 }
849 for (i = 0; i < filter_count; i++) {
Bogdan Drutu441499a2016-01-26 19:16:04 -0800850 server->channel_filters[i + 1u + (census_enabled ? 1u : 0u)] = filters[i];
Craig Tillera82950e2015-09-22 12:33:20 -0700851 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800852
Craig Tillera82950e2015-09-22 12:33:20 -0700853 server->channel_args = grpc_channel_args_copy(args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800854
855 return server;
856}
857
Craig Tillera82950e2015-09-22 12:33:20 -0700858static int streq(const char *a, const char *b) {
859 if (a == NULL && b == NULL) return 1;
860 if (a == NULL) return 0;
861 if (b == NULL) return 0;
862 return 0 == strcmp(a, b);
Craig Tiller24be0f72015-02-10 14:04:22 -0800863}
864
Craig Tillera82950e2015-09-22 12:33:20 -0700865void *grpc_server_register_method(grpc_server *server, const char *method,
Craig Tiller5987c702016-03-09 16:55:23 -0800866 const char *host, uint32_t flags) {
Craig Tiller24be0f72015-02-10 14:04:22 -0800867 registered_method *m;
Craig Tillerb2906862016-03-10 06:50:07 -0800868 GRPC_API_TRACE(
869 "grpc_server_register_method(server=%p, method=%s, host=%s, "
870 "flags=0x%08x)",
871 4, (server, method, host, flags));
Craig Tillera82950e2015-09-22 12:33:20 -0700872 if (!method) {
873 gpr_log(GPR_ERROR,
874 "grpc_server_register_method method string cannot be NULL");
875 return NULL;
876 }
877 for (m = server->registered_methods; m; m = m->next) {
878 if (streq(m->method, method) && streq(m->host, host)) {
879 gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
880 host ? host : "*");
Craig Tiller24be0f72015-02-10 14:04:22 -0800881 return NULL;
882 }
Craig Tillera82950e2015-09-22 12:33:20 -0700883 }
Craig Tillerb2906862016-03-10 06:50:07 -0800884 if ((flags & ~GRPC_INITIAL_METADATA_USED_MASK) != 0) {
885 gpr_log(GPR_ERROR, "grpc_server_register_method invalid flags 0x%08x",
886 flags);
887 return NULL;
888 }
Craig Tillera82950e2015-09-22 12:33:20 -0700889 m = gpr_malloc(sizeof(registered_method));
890 memset(m, 0, sizeof(*m));
891 request_matcher_init(&m->request_matcher, server->max_requested_calls);
892 m->method = gpr_strdup(method);
893 m->host = gpr_strdup(host);
Craig Tiller24be0f72015-02-10 14:04:22 -0800894 m->next = server->registered_methods;
Craig Tillerb2906862016-03-10 06:50:07 -0800895 m->flags = flags;
Craig Tiller24be0f72015-02-10 14:04:22 -0800896 server->registered_methods = m;
897 return m;
898}
899
Craig Tillera82950e2015-09-22 12:33:20 -0700900void grpc_server_start(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800901 listener *l;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800902 size_t i;
Craig Tillerf5768a62015-09-22 10:54:34 -0700903 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800904
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700905 GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
906
Craig Tillera82950e2015-09-22 12:33:20 -0700907 server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
908 for (i = 0; i < server->cq_count; i++) {
909 server->pollsets[i] = grpc_cq_pollset(server->cqs[i]);
910 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800911
Craig Tillera82950e2015-09-22 12:33:20 -0700912 for (l = server->listeners; l; l = l->next) {
913 l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count);
914 }
Craig Tillerdfff1b82015-09-21 14:39:57 -0700915
Craig Tillera82950e2015-09-22 12:33:20 -0700916 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800917}
918
Craig Tillera82950e2015-09-22 12:33:20 -0700919void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
920 grpc_transport *transport,
921 grpc_channel_filter const **extra_filters,
Craig Tillerb2b42612015-11-20 12:02:17 -0800922 size_t num_extra_filters,
Craig Tillera82950e2015-09-22 12:33:20 -0700923 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800924 size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700925 grpc_channel_filter const **filters =
926 gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800927 size_t i;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800928 size_t num_registered_methods;
929 size_t alloc;
930 registered_method *rm;
931 channel_registered_method *crm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800932 grpc_channel *channel;
933 channel_data *chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800934 grpc_mdstr *host;
935 grpc_mdstr *method;
Craig Tiller7536af02015-12-22 13:49:30 -0800936 uint32_t hash;
Craig Tillerf96dfc32015-09-10 14:43:18 -0700937 size_t slots;
Craig Tiller7536af02015-12-22 13:49:30 -0800938 uint32_t probes;
939 uint32_t max_probes = 0;
Craig Tillere039f032015-06-25 12:54:23 -0700940 grpc_transport_op op;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800941
Craig Tillera82950e2015-09-22 12:33:20 -0700942 for (i = 0; i < s->channel_filter_count; i++) {
943 filters[i] = s->channel_filters[i];
944 }
945 for (; i < s->channel_filter_count + num_extra_filters; i++) {
946 filters[i] = extra_filters[i - s->channel_filter_count];
947 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800948 filters[i] = &grpc_connected_channel_filter;
949
Craig Tillera82950e2015-09-22 12:33:20 -0700950 for (i = 0; i < s->cq_count; i++) {
951 memset(&op, 0, sizeof(op));
952 op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
953 grpc_transport_perform_op(exec_ctx, transport, &op);
954 }
ctillerd79b4862014-12-17 16:36:59 -0800955
Craig Tillera82950e2015-09-22 12:33:20 -0700956 channel = grpc_channel_create_from_filters(exec_ctx, NULL, filters,
Craig Tillerb2b42612015-11-20 12:02:17 -0800957 num_filters, args, 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700958 chand = (channel_data *)grpc_channel_stack_element(
Craig Tiller5987c702016-03-09 16:55:23 -0800959 grpc_channel_get_channel_stack(channel), 0)
960 ->channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800961 chand->server = s;
Craig Tillera82950e2015-09-22 12:33:20 -0700962 server_ref(s);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800963 chand->channel = channel;
964
Craig Tiller04cc8be2015-02-10 16:11:22 -0800965 num_registered_methods = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700966 for (rm = s->registered_methods; rm; rm = rm->next) {
967 num_registered_methods++;
968 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800969 /* build a lookup table phrased in terms of mdstr's in this channels context
970 to quickly find registered methods */
Craig Tillera82950e2015-09-22 12:33:20 -0700971 if (num_registered_methods > 0) {
972 slots = 2 * num_registered_methods;
973 alloc = sizeof(channel_registered_method) * slots;
974 chand->registered_methods = gpr_malloc(alloc);
975 memset(chand->registered_methods, 0, alloc);
976 for (rm = s->registered_methods; rm; rm = rm->next) {
Craig Tillerb2b42612015-11-20 12:02:17 -0800977 host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL;
978 method = grpc_mdstr_from_string(rm->method);
Craig Tillera82950e2015-09-22 12:33:20 -0700979 hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
980 for (probes = 0; chand->registered_methods[(hash + probes) % slots]
Craig Tiller5987c702016-03-09 16:55:23 -0800981 .server_registered_method != NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700982 probes++)
983 ;
984 if (probes > max_probes) max_probes = probes;
985 crm = &chand->registered_methods[(hash + probes) % slots];
986 crm->server_registered_method = rm;
Craig Tillerb2906862016-03-10 06:50:07 -0800987 crm->flags = rm->flags;
Craig Tillera82950e2015-09-22 12:33:20 -0700988 crm->host = host;
989 crm->method = method;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800990 }
Craig Tiller7536af02015-12-22 13:49:30 -0800991 GPR_ASSERT(slots <= UINT32_MAX);
992 chand->registered_method_slots = (uint32_t)slots;
Craig Tillera82950e2015-09-22 12:33:20 -0700993 chand->registered_method_max_probes = max_probes;
994 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800995
Craig Tillera82950e2015-09-22 12:33:20 -0700996 grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
997 transport);
Craig Tiller7bd5ab12015-02-17 22:29:04 -0800998
Craig Tillera82950e2015-09-22 12:33:20 -0700999 gpr_mu_lock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001000 chand->next = &s->root_channel_data;
1001 chand->prev = chand->next->prev;
1002 chand->next->prev = chand->prev->next = chand;
Craig Tillera82950e2015-09-22 12:33:20 -07001003 gpr_mu_unlock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001004
Craig Tiller565b18b2015-09-23 10:09:42 -07001005 gpr_free((void *)filters);
Craig Tiller4b804102015-06-26 16:16:12 -07001006
Craig Tillera82950e2015-09-22 12:33:20 -07001007 GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity");
1008 memset(&op, 0, sizeof(op));
Craig Tillerd7f12e32016-03-03 10:08:31 -08001009 op.set_accept_stream = true;
1010 op.set_accept_stream_fn = accept_stream;
Craig Tiller4b804102015-06-26 16:16:12 -07001011 op.set_accept_stream_user_data = chand;
1012 op.on_connectivity_state_change = &chand->channel_connectivity_changed;
1013 op.connectivity_state = &chand->connectivity_state;
Craig Tillera82950e2015-09-22 12:33:20 -07001014 op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0;
1015 grpc_transport_perform_op(exec_ctx, transport, &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001016}
1017
Craig Tillera82950e2015-09-22 12:33:20 -07001018void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg,
1019 grpc_cq_completion *storage) {
1020 (void)done_arg;
1021 gpr_free(storage);
murgatroid9900a3dab2015-08-19 11:15:38 -07001022}
1023
Craig Tillera82950e2015-09-22 12:33:20 -07001024static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s,
Craig Tiller6c396862016-01-28 13:53:40 -08001025 bool success) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001026 grpc_server *server = s;
Craig Tillera82950e2015-09-22 12:33:20 -07001027 gpr_mu_lock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001028 server->listeners_destroyed++;
Craig Tillera82950e2015-09-22 12:33:20 -07001029 maybe_finish_shutdown(exec_ctx, server);
1030 gpr_mu_unlock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001031}
1032
Craig Tillera82950e2015-09-22 12:33:20 -07001033void grpc_server_shutdown_and_notify(grpc_server *server,
1034 grpc_completion_queue *cq, void *tag) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001035 listener *l;
Craig Tillerbce999f2015-05-27 09:55:51 -07001036 shutdown_tag *sdt;
Craig Tillerff3ae682015-06-29 17:44:04 -07001037 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001038 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001039
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001040 GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3,
1041 (server, cq, tag));
1042
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001043 /* lock, and gather up some stuff to do */
Craig Tillera82950e2015-09-22 12:33:20 -07001044 gpr_mu_lock(&server->mu_global);
Craig Tiller4bf29282015-12-14 11:25:48 -08001045 grpc_cq_begin_op(cq, tag);
Craig Tillera82950e2015-09-22 12:33:20 -07001046 if (server->shutdown_published) {
1047 grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL,
1048 gpr_malloc(sizeof(grpc_cq_completion)));
1049 gpr_mu_unlock(&server->mu_global);
1050 goto done;
1051 }
1052 server->shutdown_tags =
1053 gpr_realloc(server->shutdown_tags,
1054 sizeof(shutdown_tag) * (server->num_shutdown_tags + 1));
Craig Tillerbce999f2015-05-27 09:55:51 -07001055 sdt = &server->shutdown_tags[server->num_shutdown_tags++];
1056 sdt->tag = tag;
1057 sdt->cq = cq;
Craig Tillera82950e2015-09-22 12:33:20 -07001058 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1059 gpr_mu_unlock(&server->mu_global);
1060 goto done;
1061 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001062
Craig Tillera82950e2015-09-22 12:33:20 -07001063 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
Craig Tillerab54f792015-07-08 08:34:20 -07001064
Craig Tillera82950e2015-09-22 12:33:20 -07001065 channel_broadcaster_init(server, &broadcaster);
nnoble0c475f02014-12-05 15:37:39 -08001066
Craig Tillerfc193e12015-09-24 15:29:03 -07001067 gpr_atm_rel_store(&server->shutdown_flag, 1);
1068
Craig Tillerbd217572015-02-11 18:10:56 -08001069 /* collect all unregistered then registered calls */
Craig Tillera82950e2015-09-22 12:33:20 -07001070 gpr_mu_lock(&server->mu_call);
1071 kill_pending_work_locked(&exec_ctx, server);
1072 gpr_mu_unlock(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001073
Craig Tillera82950e2015-09-22 12:33:20 -07001074 maybe_finish_shutdown(&exec_ctx, server);
1075 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001076
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001077 /* Shutdown listeners */
Craig Tillera82950e2015-09-22 12:33:20 -07001078 for (l = server->listeners; l; l = l->next) {
1079 grpc_closure_init(&l->destroy_done, listener_destroy_done, server);
1080 l->destroy(&exec_ctx, server, l->arg, &l->destroy_done);
1081 }
Craig Tillerff3ae682015-06-29 17:44:04 -07001082
Craig Tillera82950e2015-09-22 12:33:20 -07001083 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001084
Craig Tillerdfff1b82015-09-21 14:39:57 -07001085done:
Craig Tillera82950e2015-09-22 12:33:20 -07001086 grpc_exec_ctx_finish(&exec_ctx);
Craig Tilleraec96aa2015-04-07 14:32:15 -07001087}
1088
Craig Tillera82950e2015-09-22 12:33:20 -07001089void grpc_server_cancel_all_calls(grpc_server *server) {
Craig Tiller092d8d12015-07-04 22:35:00 -07001090 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001091 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillerafa2d632015-05-26 16:39:13 -07001092
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001093 GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server));
1094
Craig Tillera82950e2015-09-22 12:33:20 -07001095 gpr_mu_lock(&server->mu_global);
1096 channel_broadcaster_init(server, &broadcaster);
1097 gpr_mu_unlock(&server->mu_global);
Craig Tillerafa2d632015-05-26 16:39:13 -07001098
Craig Tillera82950e2015-09-22 12:33:20 -07001099 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1);
1100 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerafa2d632015-05-26 16:39:13 -07001101}
1102
Craig Tillera82950e2015-09-22 12:33:20 -07001103void grpc_server_destroy(grpc_server *server) {
Craig Tilleraec96aa2015-04-07 14:32:15 -07001104 listener *l;
Craig Tillerf5768a62015-09-22 10:54:34 -07001105 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller872af022015-04-24 15:57:52 -07001106
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001107 GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server));
1108
Craig Tillera82950e2015-09-22 12:33:20 -07001109 gpr_mu_lock(&server->mu_global);
1110 GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners);
1111 GPR_ASSERT(server->listeners_destroyed == num_listeners(server));
Craig Tilleraec96aa2015-04-07 14:32:15 -07001112
Craig Tillera82950e2015-09-22 12:33:20 -07001113 while (server->listeners) {
1114 l = server->listeners;
1115 server->listeners = l->next;
1116 gpr_free(l);
1117 }
Craig Tilleraec96aa2015-04-07 14:32:15 -07001118
Craig Tillera82950e2015-09-22 12:33:20 -07001119 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001120
Craig Tillera82950e2015-09-22 12:33:20 -07001121 server_unref(&exec_ctx, server);
1122 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001123}
1124
Craig Tillera82950e2015-09-22 12:33:20 -07001125void grpc_server_add_listener(
1126 grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1127 void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1128 grpc_pollset **pollsets, size_t pollset_count),
1129 void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1130 grpc_closure *on_done)) {
1131 listener *l = gpr_malloc(sizeof(listener));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001132 l->arg = arg;
1133 l->start = start;
1134 l->destroy = destroy;
1135 l->next = server->listeners;
1136 server->listeners = l;
1137}
1138
Craig Tillera82950e2015-09-22 12:33:20 -07001139static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1140 grpc_server *server,
1141 requested_call *rc) {
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001142 call_data *calld = NULL;
Craig Tillerb9d35962015-09-11 13:31:16 -07001143 request_matcher *rm = NULL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001144 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -07001145 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1146 fail_call(exec_ctx, server, rc);
1147 return GRPC_CALL_OK;
1148 }
1149 request_id = gpr_stack_lockfree_pop(server->request_freelist);
1150 if (request_id == -1) {
1151 /* out of request ids: just fail this one */
1152 fail_call(exec_ctx, server, rc);
1153 return GRPC_CALL_OK;
1154 }
1155 switch (rc->type) {
Craig Tiller04cc8be2015-02-10 16:11:22 -08001156 case BATCH_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001157 rm = &server->unregistered_request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001158 break;
1159 case REGISTERED_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001160 rm = &rc->data.registered.registered_method->request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001161 break;
Craig Tillera82950e2015-09-22 12:33:20 -07001162 }
Craig Tiller45724b32015-09-22 10:42:19 -07001163 server->requested_calls[request_id] = *rc;
Craig Tillera82950e2015-09-22 12:33:20 -07001164 gpr_free(rc);
Craig Tillerb9d35962015-09-11 13:31:16 -07001165 if (gpr_stack_lockfree_push(rm->requests, request_id)) {
Craig Tillera82950e2015-09-22 12:33:20 -07001166 /* this was the first queued request: we need to lock and start
1167 matching calls */
1168 gpr_mu_lock(&server->mu_call);
Craig Tillerb9d35962015-09-11 13:31:16 -07001169 while ((calld = rm->pending_head) != NULL) {
1170 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -07001171 if (request_id == -1) break;
Craig Tillerb9d35962015-09-11 13:31:16 -07001172 rm->pending_head = calld->pending_next;
Craig Tillera82950e2015-09-22 12:33:20 -07001173 gpr_mu_unlock(&server->mu_call);
1174 gpr_mu_lock(&calld->mu_state);
1175 if (calld->state == ZOMBIED) {
1176 gpr_mu_unlock(&calld->mu_state);
1177 grpc_closure_init(
1178 &calld->kill_zombie_closure, kill_zombie,
1179 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
Craig Tiller6c396862016-01-28 13:53:40 -08001180 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true,
1181 NULL);
Craig Tillera82950e2015-09-22 12:33:20 -07001182 } else {
1183 GPR_ASSERT(calld->state == PENDING);
1184 calld->state = ACTIVATED;
1185 gpr_mu_unlock(&calld->mu_state);
1186 begin_call(exec_ctx, server, calld,
1187 &server->requested_calls[request_id]);
1188 }
1189 gpr_mu_lock(&server->mu_call);
Craig Tiller45724b32015-09-22 10:42:19 -07001190 }
Craig Tillera82950e2015-09-22 12:33:20 -07001191 gpr_mu_unlock(&server->mu_call);
1192 }
Craig Tiller6a006ce2015-07-13 16:25:40 -07001193 return GRPC_CALL_OK;
Craig Tillercce17ac2015-01-20 09:29:28 -08001194}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001195
Craig Tillera82950e2015-09-22 12:33:20 -07001196grpc_call_error grpc_server_request_call(
1197 grpc_server *server, grpc_call **call, grpc_call_details *details,
1198 grpc_metadata_array *initial_metadata,
1199 grpc_completion_queue *cq_bound_to_call,
1200 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001201 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001202 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001203 requested_call *rc = gpr_malloc(sizeof(*rc));
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001204 GRPC_API_TRACE(
1205 "grpc_server_request_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001206 "server=%p, call=%p, details=%p, initial_metadata=%p, "
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001207 "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001208 7, (server, call, details, initial_metadata, cq_bound_to_call,
1209 cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001210 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1211 gpr_free(rc);
1212 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1213 goto done;
1214 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001215 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller9928d392015-08-18 09:40:24 -07001216 details->reserved = NULL;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001217 rc->type = BATCH_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001218 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001219 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.batch.details = details;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001224 rc->initial_metadata = initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -07001225 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001226done:
Craig Tillera82950e2015-09-22 12:33:20 -07001227 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001228 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001229}
1230
Craig Tillera82950e2015-09-22 12:33:20 -07001231grpc_call_error grpc_server_request_registered_call(
Craig Tillerb9d35962015-09-11 13:31:16 -07001232 grpc_server *server, void *rmp, grpc_call **call, gpr_timespec *deadline,
Craig Tillera82950e2015-09-22 12:33:20 -07001233 grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload,
1234 grpc_completion_queue *cq_bound_to_call,
1235 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001236 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001237 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001238 requested_call *rc = gpr_malloc(sizeof(*rc));
Craig Tillerb9d35962015-09-11 13:31:16 -07001239 registered_method *rm = rmp;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001240 GRPC_API_TRACE(
1241 "grpc_server_request_registered_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001242 "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, "
1243 "optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
1244 "tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001245 9, (server, rmp, call, deadline, initial_metadata, optional_payload,
1246 cq_bound_to_call, cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001247 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1248 gpr_free(rc);
1249 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1250 goto done;
1251 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001252 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001253 rc->type = REGISTERED_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001254 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001255 rc->tag = tag;
1256 rc->cq_bound_to_call = cq_bound_to_call;
1257 rc->cq_for_notification = cq_for_notification;
1258 rc->call = call;
Craig Tillerb9d35962015-09-11 13:31:16 -07001259 rc->data.registered.registered_method = rm;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001260 rc->data.registered.deadline = deadline;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001261 rc->initial_metadata = initial_metadata;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001262 rc->data.registered.optional_payload = optional_payload;
Craig Tillera82950e2015-09-22 12:33:20 -07001263 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001264done:
Craig Tillera82950e2015-09-22 12:33:20 -07001265 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001266 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001267}
1268
Craig Tillera82950e2015-09-22 12:33:20 -07001269static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx,
Craig Tiller6c396862016-01-28 13:53:40 -08001270 void *user_data, bool success);
Craig Tiller24be0f72015-02-10 14:04:22 -08001271
Craig Tillera82950e2015-09-22 12:33:20 -07001272static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
Craig Tiller166e2502015-02-03 20:14:41 -08001273 gpr_slice slice = value->slice;
Craig Tillera82950e2015-09-22 12:33:20 -07001274 size_t len = GPR_SLICE_LENGTH(slice);
Craig Tiller166e2502015-02-03 20:14:41 -08001275
Craig Tillera82950e2015-09-22 12:33:20 -07001276 if (len + 1 > *capacity) {
1277 *capacity = GPR_MAX(len + 1, *capacity * 2);
1278 *dest = gpr_realloc(*dest, *capacity);
1279 }
1280 memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
Craig Tiller166e2502015-02-03 20:14:41 -08001281}
1282
Craig Tillera82950e2015-09-22 12:33:20 -07001283static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1284 call_data *calld, requested_call *rc) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001285 grpc_op ops[1];
1286 grpc_op *op = ops;
1287
1288 memset(ops, 0, sizeof(ops));
Craig Tiller24be0f72015-02-10 14:04:22 -08001289
1290 /* called once initial metadata has been read by the call, but BEFORE
1291 the ioreq to fetch it out of the call has been executed.
1292 This means metadata related fields can be relied on in calld, but to
1293 fill in the metadata array passed by the client, we need to perform
1294 an ioreq op, that should complete immediately. */
1295
Craig Tillera82950e2015-09-22 12:33:20 -07001296 grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001297 grpc_closure_init(&rc->publish, publish_registered_or_batch, rc);
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001298 *rc->call = calld->call;
1299 calld->cq_new = rc->cq_for_notification;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001300 GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
Craig Tillera82950e2015-09-22 12:33:20 -07001301 switch (rc->type) {
Craig Tiller24be0f72015-02-10 14:04:22 -08001302 case BATCH_CALL:
Craig Tillera82950e2015-09-22 12:33:20 -07001303 GPR_ASSERT(calld->host != NULL);
1304 GPR_ASSERT(calld->path != NULL);
1305 cpstr(&rc->data.batch.details->host,
1306 &rc->data.batch.details->host_capacity, calld->host);
1307 cpstr(&rc->data.batch.details->method,
1308 &rc->data.batch.details->method_capacity, calld->path);
Masood Malekghassemibf177c82015-04-27 12:14:38 -07001309 rc->data.batch.details->deadline = calld->deadline;
Craig Tillerb2906862016-03-10 06:50:07 -08001310 rc->data.batch.details->flags =
1311 0 | (calld->recv_idempotent_request
1312 ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
1313 : 0);
Craig Tiller24be0f72015-02-10 14:04:22 -08001314 break;
1315 case REGISTERED_CALL:
1316 *rc->data.registered.deadline = calld->deadline;
Craig Tillera82950e2015-09-22 12:33:20 -07001317 if (rc->data.registered.optional_payload) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001318 op->op = GRPC_OP_RECV_MESSAGE;
1319 op->data.recv_message = rc->data.registered.optional_payload;
1320 op++;
Craig Tillera82950e2015-09-22 12:33:20 -07001321 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001322 break;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001323 default:
1324 GPR_UNREACHABLE_CODE(return );
Craig Tillera82950e2015-09-22 12:33:20 -07001325 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001326
Craig Tillera82950e2015-09-22 12:33:20 -07001327 GRPC_CALL_INTERNAL_REF(calld->call, "server");
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001328 grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops,
1329 (size_t)(op - ops), &rc->publish);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001330}
1331
Craig Tillera82950e2015-09-22 12:33:20 -07001332static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
1333 grpc_cq_completion *c) {
Craig Tiller6a006ce2015-07-13 16:25:40 -07001334 requested_call *rc = req;
1335 grpc_server *server = rc->server;
1336
Craig Tillera82950e2015-09-22 12:33:20 -07001337 if (rc >= server->requested_calls &&
1338 rc < server->requested_calls + server->max_requested_calls) {
1339 GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
1340 gpr_stack_lockfree_push(server->request_freelist,
1341 (int)(rc - server->requested_calls));
1342 } else {
1343 gpr_free(req);
1344 }
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001345
Craig Tillera82950e2015-09-22 12:33:20 -07001346 server_unref(exec_ctx, server);
Craig Tiller24be0f72015-02-10 14:04:22 -08001347}
1348
Craig Tillera82950e2015-09-22 12:33:20 -07001349static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1350 requested_call *rc) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001351 *rc->call = NULL;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001352 rc->initial_metadata->count = 0;
1353
Craig Tillera82950e2015-09-22 12:33:20 -07001354 server_ref(server);
1355 grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
1356 done_request_event, rc, &rc->completion);
Craig Tiller24be0f72015-02-10 14:04:22 -08001357}
1358
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001359static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc,
Craig Tiller6c396862016-01-28 13:53:40 -08001360 bool success) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001361 requested_call *rc = prc;
1362 grpc_call *call = *rc->call;
Craig Tillera82950e2015-09-22 12:33:20 -07001363 grpc_call_element *elem =
1364 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
Craig Tiller20bc56d2015-02-12 09:02:56 -08001365 call_data *calld = elem->call_data;
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001366 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001367 server_ref(chand->server);
1368 grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event,
1369 rc, &rc->completion);
1370 GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server");
Craig Tiller24be0f72015-02-10 14:04:22 -08001371}
1372
Craig Tillera82950e2015-09-22 12:33:20 -07001373const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001374 return server->channel_args;
Craig Tiller190d3602015-02-18 09:23:38 -08001375}
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001376
Craig Tillera82950e2015-09-22 12:33:20 -07001377int grpc_server_has_open_connections(grpc_server *server) {
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001378 int r;
Craig Tillera82950e2015-09-22 12:33:20 -07001379 gpr_mu_lock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001380 r = server->root_channel_data.next != &server->root_channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001381 gpr_mu_unlock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001382 return r;
1383}