blob: e0b977256952eb851136ed57e370590e8fa50a6c [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;
104 grpc_mdstr *method;
105 grpc_mdstr *host;
106} channel_registered_method;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800107
Craig Tillera82950e2015-09-22 12:33:20 -0700108struct channel_data {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800109 grpc_server *server;
Craig Tillere039f032015-06-25 12:54:23 -0700110 grpc_connectivity_state connectivity_state;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800111 grpc_channel *channel;
112 /* linked list of all channels on a server */
113 channel_data *next;
114 channel_data *prev;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800115 channel_registered_method *registered_methods;
Craig Tiller7536af02015-12-22 13:49:30 -0800116 uint32_t registered_method_slots;
117 uint32_t registered_method_max_probes;
Craig Tiller33825112015-09-18 07:44:19 -0700118 grpc_closure finish_destroy_channel_closure;
119 grpc_closure channel_connectivity_changed;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800120};
121
Craig Tillera82950e2015-09-22 12:33:20 -0700122typedef struct shutdown_tag {
Craig Tillerbce999f2015-05-27 09:55:51 -0700123 void *tag;
124 grpc_completion_queue *cq;
Craig Tiller97fc6a32015-07-08 15:31:35 -0700125 grpc_cq_completion completion;
Craig Tillerbce999f2015-05-27 09:55:51 -0700126} shutdown_tag;
127
Craig Tillera82950e2015-09-22 12:33:20 -0700128typedef enum {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800129 /* 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
Craig Tiller729b35a2015-07-13 12:36:47 -0700139typedef struct request_matcher request_matcher;
140
Craig Tillera82950e2015-09-22 12:33:20 -0700141struct call_data {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800142 grpc_call *call;
143
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700144 /** protects state */
145 gpr_mu mu_state;
146 /** the current state of a call - see call_state */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800147 call_state state;
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700148
Craig Tillercce17ac2015-01-20 09:29:28 -0800149 grpc_mdstr *path;
150 grpc_mdstr *host;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700151 gpr_timespec deadline;
Craig Tillercce17ac2015-01-20 09:29:28 -0800152
Craig Tiller20bc56d2015-02-12 09:02:56 -0800153 grpc_completion_queue *cq_new;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800154
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800155 grpc_metadata_batch *recv_initial_metadata;
Craig Tiller4d40ba32016-03-09 17:48:40 -0800156 bool recv_idempotent_request;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800157 grpc_metadata_array initial_metadata;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700158
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800159 grpc_closure got_initial_metadata;
160 grpc_closure server_on_recv_initial_metadata;
Craig Tiller33825112015-09-18 07:44:19 -0700161 grpc_closure kill_zombie_closure;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800162 grpc_closure *on_done_recv_initial_metadata;
David Garcia Quintas284488b2015-05-28 16:27:39 -0700163
Craig Tiller729b35a2015-07-13 12:36:47 -0700164 call_data *pending_next;
165};
166
Craig Tillera82950e2015-09-22 12:33:20 -0700167struct request_matcher {
Craig Tiller729b35a2015-07-13 12:36:47 -0700168 call_data *pending_head;
169 call_data *pending_tail;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700170 gpr_stack_lockfree *requests;
Craig Tiller729b35a2015-07-13 12:36:47 -0700171};
172
Craig Tillera82950e2015-09-22 12:33:20 -0700173struct registered_method {
Craig Tiller729b35a2015-07-13 12:36:47 -0700174 char *method;
175 char *host;
176 request_matcher request_matcher;
177 registered_method *next;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800178};
179
Craig Tillera82950e2015-09-22 12:33:20 -0700180typedef struct {
Craig Tillerff3ae682015-06-29 17:44:04 -0700181 grpc_channel **channels;
182 size_t num_channels;
183} channel_broadcaster;
184
Craig Tillera82950e2015-09-22 12:33:20 -0700185struct grpc_server {
Craig Tiller729b35a2015-07-13 12:36:47 -0700186 size_t channel_filter_count;
Craig Tiller565b18b2015-09-23 10:09:42 -0700187 grpc_channel_filter const **channel_filters;
Craig Tiller729b35a2015-07-13 12:36:47 -0700188 grpc_channel_args *channel_args;
189
190 grpc_completion_queue **cqs;
191 grpc_pollset **pollsets;
192 size_t cq_count;
193
194 /* The two following mutexes control access to server-state
195 mu_global controls access to non-call-related state (e.g., channel state)
196 mu_call controls access to call-related state (e.g., the call lists)
197
198 If they are ever required to be nested, you must lock mu_global
199 before mu_call. This is currently used in shutdown processing
200 (grpc_server_shutdown_and_notify and maybe_finish_shutdown) */
Craig Tillera82950e2015-09-22 12:33:20 -0700201 gpr_mu mu_global; /* mutex for server and channel state */
202 gpr_mu mu_call; /* mutex for call-specific state */
Craig Tiller729b35a2015-07-13 12:36:47 -0700203
204 registered_method *registered_methods;
205 request_matcher unregistered_request_matcher;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700206 /** free list of available requested_calls indices */
207 gpr_stack_lockfree *request_freelist;
208 /** requested call backing data */
209 requested_call *requested_calls;
Craig Tiller32ca48c2015-09-10 11:47:15 -0700210 size_t max_requested_calls;
Craig Tiller729b35a2015-07-13 12:36:47 -0700211
Craig Tiller6a006ce2015-07-13 16:25:40 -0700212 gpr_atm shutdown_flag;
Craig Tiller7536af02015-12-22 13:49:30 -0800213 uint8_t shutdown_published;
Craig Tiller729b35a2015-07-13 12:36:47 -0700214 size_t num_shutdown_tags;
215 shutdown_tag *shutdown_tags;
216
217 channel_data root_channel_data;
218
219 listener *listeners;
220 int listeners_destroyed;
221 gpr_refcount internal_refcount;
222
223 /** when did we print the last shutdown progress message */
224 gpr_timespec last_shutdown_message_time;
225};
226
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800227#define SERVER_FROM_CALL_ELEM(elem) \
228 (((channel_data *)(elem)->channel_data)->server)
229
Craig Tillera82950e2015-09-22 12:33:20 -0700230static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
231 call_data *calld, requested_call *rc);
232static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
233 requested_call *rc);
Vijay Pai8931cdd2015-06-17 12:42:17 -0700234/* Before calling maybe_finish_shutdown, we must hold mu_global and not
235 hold mu_call */
Craig Tillera82950e2015-09-22 12:33:20 -0700236static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server);
Craig Tiller24be0f72015-02-10 14:04:22 -0800237
Craig Tiller729b35a2015-07-13 12:36:47 -0700238/*
239 * channel broadcaster
240 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700241
242/* assumes server locked */
Craig Tillera82950e2015-09-22 12:33:20 -0700243static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700244 channel_data *c;
245 size_t count = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700246 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
247 count++;
248 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700249 cb->num_channels = count;
Craig Tillera82950e2015-09-22 12:33:20 -0700250 cb->channels = gpr_malloc(sizeof(*cb->channels) * cb->num_channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700251 count = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700252 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
253 cb->channels[count++] = c->channel;
254 GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast");
255 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700256}
257
Craig Tillera82950e2015-09-22 12:33:20 -0700258struct shutdown_cleanup_args {
Craig Tiller33825112015-09-18 07:44:19 -0700259 grpc_closure closure;
Craig Tillerff3ae682015-06-29 17:44:04 -0700260 gpr_slice slice;
261};
262
Craig Tillera82950e2015-09-22 12:33:20 -0700263static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
Craig Tiller6c396862016-01-28 13:53:40 -0800264 bool iomgr_status_ignored) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700265 struct shutdown_cleanup_args *a = arg;
Craig Tillera82950e2015-09-22 12:33:20 -0700266 gpr_slice_unref(a->slice);
267 gpr_free(a);
Craig Tillerff3ae682015-06-29 17:44:04 -0700268}
269
Craig Tillera82950e2015-09-22 12:33:20 -0700270static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
271 int send_goaway, int send_disconnect) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700272 grpc_transport_op op;
273 struct shutdown_cleanup_args *sc;
274 grpc_channel_element *elem;
275
Craig Tillera82950e2015-09-22 12:33:20 -0700276 memset(&op, 0, sizeof(op));
Craig Tillerff3ae682015-06-29 17:44:04 -0700277 op.send_goaway = send_goaway;
Craig Tillera82950e2015-09-22 12:33:20 -0700278 sc = gpr_malloc(sizeof(*sc));
279 sc->slice = gpr_slice_from_copied_string("Server shutdown");
Craig Tillerff3ae682015-06-29 17:44:04 -0700280 op.goaway_message = &sc->slice;
281 op.goaway_status = GRPC_STATUS_OK;
282 op.disconnect = send_disconnect;
Craig Tillera82950e2015-09-22 12:33:20 -0700283 grpc_closure_init(&sc->closure, shutdown_cleanup, sc);
Craig Tillerff3ae682015-06-29 17:44:04 -0700284 op.on_consumed = &sc->closure;
285
Craig Tillera82950e2015-09-22 12:33:20 -0700286 elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
287 elem->filter->start_transport_op(exec_ctx, elem, &op);
Craig Tillerff3ae682015-06-29 17:44:04 -0700288}
289
Craig Tillera82950e2015-09-22 12:33:20 -0700290static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx,
291 channel_broadcaster *cb,
292 int send_goaway,
293 int force_disconnect) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700294 size_t i;
295
Craig Tillera82950e2015-09-22 12:33:20 -0700296 for (i = 0; i < cb->num_channels; i++) {
297 send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect);
298 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast");
299 }
300 gpr_free(cb->channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700301}
302
Craig Tiller729b35a2015-07-13 12:36:47 -0700303/*
304 * request_matcher
305 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700306
Craig Tiller8dc09712015-09-24 13:58:16 -0700307static void request_matcher_init(request_matcher *rm, size_t entries) {
Craig Tillerb9d35962015-09-11 13:31:16 -0700308 memset(rm, 0, sizeof(*rm));
309 rm->requests = gpr_stack_lockfree_create(entries);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800310}
311
Craig Tillerb9d35962015-09-11 13:31:16 -0700312static void request_matcher_destroy(request_matcher *rm) {
313 GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests) == -1);
314 gpr_stack_lockfree_destroy(rm->requests);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800315}
316
Craig Tiller6c396862016-01-28 13:53:40 -0800317static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, bool success) {
Craig Tillera82950e2015-09-22 12:33:20 -0700318 grpc_call_destroy(grpc_call_from_top_element(elem));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800319}
320
Craig Tiller8dc09712015-09-24 13:58:16 -0700321static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx,
322 request_matcher *rm) {
Craig Tillerb9d35962015-09-11 13:31:16 -0700323 while (rm->pending_head) {
324 call_data *calld = rm->pending_head;
325 rm->pending_head = calld->pending_next;
Craig Tillera82950e2015-09-22 12:33:20 -0700326 gpr_mu_lock(&calld->mu_state);
327 calld->state = ZOMBIED;
328 gpr_mu_unlock(&calld->mu_state);
329 grpc_closure_init(
330 &calld->kill_zombie_closure, kill_zombie,
331 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
Craig Tiller6c396862016-01-28 13:53:40 -0800332 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillera82950e2015-09-22 12:33:20 -0700333 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800334}
335
Craig Tillera82950e2015-09-22 12:33:20 -0700336static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx,
337 grpc_server *server,
338 request_matcher *rm) {
Craig Tiller1191e212015-07-30 14:49:02 -0700339 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -0700340 while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) {
341 fail_call(exec_ctx, server, &server->requested_calls[request_id]);
342 }
Craig Tiller1191e212015-07-30 14:49:02 -0700343}
344
Craig Tiller729b35a2015-07-13 12:36:47 -0700345/*
346 * server proper
347 */
348
Craig Tillera82950e2015-09-22 12:33:20 -0700349static void server_ref(grpc_server *server) {
350 gpr_ref(&server->internal_refcount);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800351}
352
Craig Tillera82950e2015-09-22 12:33:20 -0700353static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800354 registered_method *rm;
Craig Tiller89504612015-04-27 11:48:46 -0700355 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700356 grpc_channel_args_destroy(server->channel_args);
357 gpr_mu_destroy(&server->mu_global);
358 gpr_mu_destroy(&server->mu_call);
Craig Tiller565b18b2015-09-23 10:09:42 -0700359 gpr_free((void *)server->channel_filters);
Craig Tillera82950e2015-09-22 12:33:20 -0700360 while ((rm = server->registered_methods) != NULL) {
361 server->registered_methods = rm->next;
362 request_matcher_destroy(&rm->request_matcher);
363 gpr_free(rm->method);
364 gpr_free(rm->host);
365 gpr_free(rm);
366 }
367 for (i = 0; i < server->cq_count; i++) {
368 GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server");
369 }
370 request_matcher_destroy(&server->unregistered_request_matcher);
371 gpr_stack_lockfree_destroy(server->request_freelist);
372 gpr_free(server->cqs);
373 gpr_free(server->pollsets);
374 gpr_free(server->shutdown_tags);
375 gpr_free(server->requested_calls);
376 gpr_free(server);
Craig Tilleree945e82015-05-26 16:15:34 -0700377}
378
Craig Tillera82950e2015-09-22 12:33:20 -0700379static void server_unref(grpc_exec_ctx *exec_ctx, grpc_server *server) {
380 if (gpr_unref(&server->internal_refcount)) {
381 server_delete(exec_ctx, server);
382 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800383}
384
Craig Tillera82950e2015-09-22 12:33:20 -0700385static int is_channel_orphaned(channel_data *chand) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800386 return chand->next == chand;
387}
388
Craig Tillera82950e2015-09-22 12:33:20 -0700389static void orphan_channel(channel_data *chand) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800390 chand->next->prev = chand->prev;
391 chand->prev->next = chand->next;
392 chand->next = chand->prev = chand;
393}
394
Craig Tillera82950e2015-09-22 12:33:20 -0700395static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd,
Craig Tiller6c396862016-01-28 13:53:40 -0800396 bool success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800397 channel_data *chand = cd;
398 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700399 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server");
400 server_unref(exec_ctx, server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800401}
402
Craig Tillera82950e2015-09-22 12:33:20 -0700403static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) {
404 if (is_channel_orphaned(chand)) return;
405 GPR_ASSERT(chand->server != NULL);
406 orphan_channel(chand);
407 server_ref(chand->server);
408 maybe_finish_shutdown(exec_ctx, chand->server);
David Garcia Quintas284488b2015-05-28 16:27:39 -0700409 chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
410 chand->finish_destroy_channel_closure.cb_arg = chand;
Craig Tillerd7f12e32016-03-03 10:08:31 -0800411
412 grpc_transport_op op;
413 memset(&op, 0, sizeof(op));
414 op.set_accept_stream = true;
415 op.on_consumed = &chand->finish_destroy_channel_closure;
416 grpc_channel_next_op(exec_ctx,
417 grpc_channel_stack_element(
418 grpc_channel_get_channel_stack(chand->channel), 0),
419 &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800420}
421
Craig Tillera82950e2015-09-22 12:33:20 -0700422static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server,
Craig Tiller8dc09712015-09-24 13:58:16 -0700423 grpc_call_element *elem, request_matcher *rm) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800424 call_data *calld = elem->call_data;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700425 int request_id;
426
Craig Tillera82950e2015-09-22 12:33:20 -0700427 if (gpr_atm_acq_load(&server->shutdown_flag)) {
428 gpr_mu_lock(&calld->mu_state);
429 calld->state = ZOMBIED;
430 gpr_mu_unlock(&calld->mu_state);
431 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller6c396862016-01-28 13:53:40 -0800432 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillera82950e2015-09-22 12:33:20 -0700433 return;
434 }
Craig Tiller45724b32015-09-22 10:42:19 -0700435
Craig Tillerb9d35962015-09-11 13:31:16 -0700436 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -0700437 if (request_id == -1) {
438 gpr_mu_lock(&server->mu_call);
439 gpr_mu_lock(&calld->mu_state);
440 calld->state = PENDING;
441 gpr_mu_unlock(&calld->mu_state);
Craig Tillerb9d35962015-09-11 13:31:16 -0700442 if (rm->pending_head == NULL) {
443 rm->pending_tail = rm->pending_head = calld;
Craig Tillera82950e2015-09-22 12:33:20 -0700444 } else {
Craig Tillerb9d35962015-09-11 13:31:16 -0700445 rm->pending_tail->pending_next = calld;
446 rm->pending_tail = calld;
Craig Tiller45724b32015-09-22 10:42:19 -0700447 }
Craig Tillera82950e2015-09-22 12:33:20 -0700448 calld->pending_next = NULL;
449 gpr_mu_unlock(&server->mu_call);
450 } else {
451 gpr_mu_lock(&calld->mu_state);
452 calld->state = ACTIVATED;
453 gpr_mu_unlock(&calld->mu_state);
454 begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
455 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800456}
457
Craig Tillera82950e2015-09-22 12:33:20 -0700458static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800459 channel_data *chand = elem->channel_data;
460 call_data *calld = elem->call_data;
461 grpc_server *server = chand->server;
Craig Tiller7536af02015-12-22 13:49:30 -0800462 uint32_t i;
463 uint32_t hash;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800464 channel_registered_method *rm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800465
Craig Tillera82950e2015-09-22 12:33:20 -0700466 if (chand->registered_methods && calld->path && calld->host) {
467 /* TODO(ctiller): unify these two searches */
468 /* check for an exact match with host */
469 hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
470 for (i = 0; i <= chand->registered_method_max_probes; i++) {
471 rm = &chand->registered_methods[(hash + i) %
472 chand->registered_method_slots];
473 if (!rm) break;
474 if (rm->host != calld->host) continue;
475 if (rm->method != calld->path) continue;
476 finish_start_new_rpc(exec_ctx, server, elem,
477 &rm->server_registered_method->request_matcher);
478 return;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800479 }
Craig Tillera82950e2015-09-22 12:33:20 -0700480 /* check for a wildcard method definition (no host set) */
481 hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
482 for (i = 0; i <= chand->registered_method_max_probes; i++) {
483 rm = &chand->registered_methods[(hash + i) %
484 chand->registered_method_slots];
485 if (!rm) break;
486 if (rm->host != NULL) continue;
487 if (rm->method != calld->path) continue;
488 finish_start_new_rpc(exec_ctx, server, elem,
489 &rm->server_registered_method->request_matcher);
490 return;
491 }
492 }
493 finish_start_new_rpc(exec_ctx, server, elem,
494 &server->unregistered_request_matcher);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800495}
496
Craig Tillera82950e2015-09-22 12:33:20 -0700497static int num_listeners(grpc_server *server) {
Craig Tilleree945e82015-05-26 16:15:34 -0700498 listener *l;
499 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700500 for (l = server->listeners; l; l = l->next) {
501 n++;
502 }
Craig Tilleree945e82015-05-26 16:15:34 -0700503 return n;
504}
505
Craig Tillera82950e2015-09-22 12:33:20 -0700506static void done_shutdown_event(grpc_exec_ctx *exec_ctx, void *server,
507 grpc_cq_completion *completion) {
508 server_unref(exec_ctx, server);
Craig Tiller97fc6a32015-07-08 15:31:35 -0700509}
510
Craig Tillera82950e2015-09-22 12:33:20 -0700511static int num_channels(grpc_server *server) {
Craig Tillerab54f792015-07-08 08:34:20 -0700512 channel_data *chand;
513 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700514 for (chand = server->root_channel_data.next;
515 chand != &server->root_channel_data; chand = chand->next) {
516 n++;
517 }
Craig Tillerab54f792015-07-08 08:34:20 -0700518 return n;
519}
520
Craig Tillera82950e2015-09-22 12:33:20 -0700521static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx,
522 grpc_server *server) {
Craig Tiller1191e212015-07-30 14:49:02 -0700523 registered_method *rm;
Craig Tillera82950e2015-09-22 12:33:20 -0700524 request_matcher_kill_requests(exec_ctx, server,
525 &server->unregistered_request_matcher);
526 request_matcher_zombify_all_pending_calls(
527 exec_ctx, &server->unregistered_request_matcher);
528 for (rm = server->registered_methods; rm; rm = rm->next) {
529 request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher);
530 request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
531 }
Craig Tillerdc627722015-05-26 15:27:02 -0700532}
533
Craig Tillera82950e2015-09-22 12:33:20 -0700534static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
535 grpc_server *server) {
Craig Tiller45724b32015-09-22 10:42:19 -0700536 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700537 if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) {
538 return;
539 }
Craig Tiller45724b32015-09-22 10:42:19 -0700540
Craig Tillera82950e2015-09-22 12:33:20 -0700541 kill_pending_work_locked(exec_ctx, server);
Craig Tiller45724b32015-09-22 10:42:19 -0700542
Craig Tillera82950e2015-09-22 12:33:20 -0700543 if (server->root_channel_data.next != &server->root_channel_data ||
544 server->listeners_destroyed < num_listeners(server)) {
545 if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
546 server->last_shutdown_message_time),
547 gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
548 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
549 gpr_log(GPR_DEBUG,
550 "Waiting for %d channels and %d/%d listeners to be destroyed"
551 " before shutting down server",
552 num_channels(server),
553 num_listeners(server) - server->listeners_destroyed,
554 num_listeners(server));
Craig Tiller45724b32015-09-22 10:42:19 -0700555 }
Craig Tillera82950e2015-09-22 12:33:20 -0700556 return;
557 }
Craig Tiller45724b32015-09-22 10:42:19 -0700558 server->shutdown_published = 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700559 for (i = 0; i < server->num_shutdown_tags; i++) {
560 server_ref(server);
561 grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq,
562 server->shutdown_tags[i].tag, 1, done_shutdown_event, server,
563 &server->shutdown_tags[i].completion);
564 }
Craig Tiller45724b32015-09-22 10:42:19 -0700565}
566
Craig Tillera82950e2015-09-22 12:33:20 -0700567static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
Craig Tiller6902ad22015-04-16 08:01:49 -0700568 grpc_call_element *elem = user_data;
Craig Tillercce17ac2015-01-20 09:29:28 -0800569 call_data *calld = elem->call_data;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800570 if (md->key == GRPC_MDSTR_PATH) {
Craig Tillera82950e2015-09-22 12:33:20 -0700571 calld->path = GRPC_MDSTR_REF(md->value);
572 return NULL;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800573 } else if (md->key == GRPC_MDSTR_AUTHORITY) {
Craig Tillera82950e2015-09-22 12:33:20 -0700574 calld->host = GRPC_MDSTR_REF(md->value);
575 return NULL;
576 }
Craig Tiller6902ad22015-04-16 08:01:49 -0700577 return md;
578}
579
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800580static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
Craig Tiller6c396862016-01-28 13:53:40 -0800581 bool success) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700582 grpc_call_element *elem = ptr;
Craig Tiller6902ad22015-04-16 08:01:49 -0700583 call_data *calld = elem->call_data;
Craig Tiller94329d02015-07-23 09:52:11 -0700584 gpr_timespec op_deadline;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700585
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800586 grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
587 op_deadline = calld->recv_initial_metadata->deadline;
588 if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
589 calld->deadline = op_deadline;
590 }
591 if (calld->host && calld->path) {
592 /* do nothing */
593 } else {
594 success = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700595 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700596
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800597 calld->on_done_recv_initial_metadata->cb(
598 exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success);
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700599}
600
Craig Tillera82950e2015-09-22 12:33:20 -0700601static void server_mutate_op(grpc_call_element *elem,
602 grpc_transport_stream_op *op) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700603 call_data *calld = elem->call_data;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700604
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800605 if (op->recv_initial_metadata != NULL) {
Craig Tiller4d40ba32016-03-09 17:48:40 -0800606 GPR_ASSERT(op->recv_idempotent_request == NULL);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800607 calld->recv_initial_metadata = op->recv_initial_metadata;
Craig Tillera44cbfc2016-02-03 16:02:49 -0800608 calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
609 op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata;
Craig Tiller4d40ba32016-03-09 17:48:40 -0800610 op->recv_idempotent_request = &calld->recv_idempotent_request;
Craig Tillera82950e2015-09-22 12:33:20 -0700611 }
Craig Tiller50d9db52015-04-23 10:52:14 -0700612}
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700613
Craig Tillera82950e2015-09-22 12:33:20 -0700614static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
615 grpc_call_element *elem,
616 grpc_transport_stream_op *op) {
617 GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
618 server_mutate_op(elem, op);
619 grpc_call_next_op(exec_ctx, elem, op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800620}
621
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800622static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
Craig Tiller6c396862016-01-28 13:53:40 -0800623 bool success) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800624 grpc_call_element *elem = ptr;
625 call_data *calld = elem->call_data;
626 if (success) {
627 start_new_rpc(exec_ctx, elem);
628 } else {
629 gpr_mu_lock(&calld->mu_state);
630 if (calld->state == NOT_STARTED) {
631 calld->state = ZOMBIED;
632 gpr_mu_unlock(&calld->mu_state);
633 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller6c396862016-01-28 13:53:40 -0800634 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800635 } else if (calld->state == PENDING) {
636 calld->state = ZOMBIED;
637 gpr_mu_unlock(&calld->mu_state);
638 /* zombied call will be destroyed when it's removed from the pending
639 queue... later */
640 } else {
641 gpr_mu_unlock(&calld->mu_state);
642 }
643 }
644}
645
646static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
647 grpc_transport *transport,
Craig Tillera82950e2015-09-22 12:33:20 -0700648 const void *transport_server_data) {
Craig Tillere039f032015-06-25 12:54:23 -0700649 channel_data *chand = cd;
650 /* create a call */
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800651 grpc_call *call =
652 grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data,
653 NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
654 grpc_call_element *elem =
655 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
656 call_data *calld = elem->call_data;
657 grpc_op op;
658 memset(&op, 0, sizeof(op));
659 op.op = GRPC_OP_RECV_INITIAL_METADATA;
660 op.data.recv_initial_metadata = &calld->initial_metadata;
661 grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem);
662 grpc_call_start_batch_and_execute(exec_ctx, call, &op, 1,
663 &calld->got_initial_metadata);
Craig Tillere039f032015-06-25 12:54:23 -0700664}
665
Craig Tillera82950e2015-09-22 12:33:20 -0700666static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd,
Craig Tiller6c396862016-01-28 13:53:40 -0800667 bool iomgr_status_ignored) {
Craig Tillere039f032015-06-25 12:54:23 -0700668 channel_data *chand = cd;
669 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700670 if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
671 grpc_transport_op op;
672 memset(&op, 0, sizeof(op));
673 op.on_connectivity_state_change = &chand->channel_connectivity_changed,
674 op.connectivity_state = &chand->connectivity_state;
675 grpc_channel_next_op(exec_ctx,
676 grpc_channel_stack_element(
677 grpc_channel_get_channel_stack(chand->channel), 0),
678 &op);
679 } else {
680 gpr_mu_lock(&server->mu_global);
681 destroy_channel(exec_ctx, chand);
682 gpr_mu_unlock(&server->mu_global);
683 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity");
684 }
Craig Tillere039f032015-06-25 12:54:23 -0700685}
686
Craig Tillera82950e2015-09-22 12:33:20 -0700687static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800688 grpc_call_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800689 call_data *calld = elem->call_data;
690 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700691 memset(calld, 0, sizeof(call_data));
692 calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
693 calld->call = grpc_call_from_top_element(elem);
694 gpr_mu_init(&calld->mu_state);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800695
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800696 grpc_closure_init(&calld->server_on_recv_initial_metadata,
697 server_on_recv_initial_metadata, elem);
Craig Tiller1e6facb2015-06-11 22:47:11 -0700698
Craig Tillera82950e2015-09-22 12:33:20 -0700699 server_ref(chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800700}
701
Craig Tillera82950e2015-09-22 12:33:20 -0700702static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
703 grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800704 channel_data *chand = elem->channel_data;
Craig Tillerdb7db992015-01-29 11:19:01 -0800705 call_data *calld = elem->call_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800706
Craig Tillera82950e2015-09-22 12:33:20 -0700707 GPR_ASSERT(calld->state != PENDING);
Craig Tiller092d8d12015-07-04 22:35:00 -0700708
Craig Tillera82950e2015-09-22 12:33:20 -0700709 if (calld->host) {
710 GRPC_MDSTR_UNREF(calld->host);
711 }
712 if (calld->path) {
713 GRPC_MDSTR_UNREF(calld->path);
714 }
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800715 grpc_metadata_array_destroy(&calld->initial_metadata);
Craig Tiller4df31a62015-01-30 09:44:31 -0800716
Craig Tillera82950e2015-09-22 12:33:20 -0700717 gpr_mu_destroy(&calld->mu_state);
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700718
Craig Tillera82950e2015-09-22 12:33:20 -0700719 server_unref(exec_ctx, chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800720}
721
Craig Tillera82950e2015-09-22 12:33:20 -0700722static void init_channel_elem(grpc_exec_ctx *exec_ctx,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800723 grpc_channel_element *elem,
724 grpc_channel_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800725 channel_data *chand = elem->channel_data;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800726 GPR_ASSERT(args->is_first);
727 GPR_ASSERT(!args->is_last);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800728 chand->server = NULL;
729 chand->channel = NULL;
730 chand->next = chand->prev = chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800731 chand->registered_methods = NULL;
Craig Tillere039f032015-06-25 12:54:23 -0700732 chand->connectivity_state = GRPC_CHANNEL_IDLE;
Craig Tillera82950e2015-09-22 12:33:20 -0700733 grpc_closure_init(&chand->channel_connectivity_changed,
734 channel_connectivity_changed, chand);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800735}
736
Craig Tillera82950e2015-09-22 12:33:20 -0700737static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
738 grpc_channel_element *elem) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800739 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800740 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700741 if (chand->registered_methods) {
742 for (i = 0; i < chand->registered_method_slots; i++) {
743 if (chand->registered_methods[i].method) {
744 GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
745 }
746 if (chand->registered_methods[i].host) {
747 GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
748 }
Craig Tillerec3257c2015-02-12 15:59:43 -0800749 }
Craig Tillera82950e2015-09-22 12:33:20 -0700750 gpr_free(chand->registered_methods);
751 }
752 if (chand->server) {
753 gpr_mu_lock(&chand->server->mu_global);
754 chand->next->prev = chand->prev;
755 chand->prev->next = chand->next;
756 chand->next = chand->prev = chand;
757 maybe_finish_shutdown(exec_ctx, chand->server);
758 gpr_mu_unlock(&chand->server->mu_global);
Craig Tillera82950e2015-09-22 12:33:20 -0700759 server_unref(exec_ctx, chand->server);
760 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800761}
762
763static const grpc_channel_filter server_surface_filter = {
Craig Tiller5987c702016-03-09 16:55:23 -0800764 server_start_transport_stream_op,
765 grpc_channel_next_op,
766 sizeof(call_data),
767 init_call_elem,
768 grpc_call_stack_ignore_set_pollset,
769 destroy_call_elem,
770 sizeof(channel_data),
771 init_channel_elem,
772 destroy_channel_elem,
773 grpc_call_next_get_peer,
774 "server",
Craig Tiller9f28ac22015-01-27 17:01:29 -0800775};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800776
Craig Tillera82950e2015-09-22 12:33:20 -0700777void grpc_server_register_completion_queue(grpc_server *server,
778 grpc_completion_queue *cq,
779 void *reserved) {
Craig Tiller20bc56d2015-02-12 09:02:56 -0800780 size_t i, n;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700781 GRPC_API_TRACE(
782 "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
783 (server, cq, reserved));
Craig Tillera82950e2015-09-22 12:33:20 -0700784 GPR_ASSERT(!reserved);
785 for (i = 0; i < server->cq_count; i++) {
786 if (server->cqs[i] == cq) return;
787 }
788 GRPC_CQ_INTERNAL_REF(cq, "server");
789 grpc_cq_mark_server_cq(cq);
Craig Tiller20bc56d2015-02-12 09:02:56 -0800790 n = server->cq_count++;
Craig Tillera82950e2015-09-22 12:33:20 -0700791 server->cqs = gpr_realloc(server->cqs,
792 server->cq_count * sizeof(grpc_completion_queue *));
Craig Tiller20bc56d2015-02-12 09:02:56 -0800793 server->cqs[n] = cq;
794}
795
Craig Tillera82950e2015-09-22 12:33:20 -0700796grpc_server *grpc_server_create_from_filters(
797 const grpc_channel_filter **filters, size_t filter_count,
798 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800799 size_t i;
Bogdan Drutu441499a2016-01-26 19:16:04 -0800800 int census_enabled = grpc_channel_args_is_census_enabled(args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800801
Craig Tillera82950e2015-09-22 12:33:20 -0700802 grpc_server *server = gpr_malloc(sizeof(grpc_server));
Craig Tiller60fd3612015-03-05 16:24:22 -0800803
Craig Tillera82950e2015-09-22 12:33:20 -0700804 GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
Craig Tiller60fd3612015-03-05 16:24:22 -0800805
Craig Tillera82950e2015-09-22 12:33:20 -0700806 memset(server, 0, sizeof(grpc_server));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800807
Craig Tillera82950e2015-09-22 12:33:20 -0700808 gpr_mu_init(&server->mu_global);
809 gpr_mu_init(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800810
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800811 /* decremented by grpc_server_destroy */
Craig Tillera82950e2015-09-22 12:33:20 -0700812 gpr_ref_init(&server->internal_refcount, 1);
813 server->root_channel_data.next = server->root_channel_data.prev =
814 &server->root_channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800815
Craig Tiller6a006ce2015-07-13 16:25:40 -0700816 /* TODO(ctiller): expose a channel_arg for this */
817 server->max_requested_calls = 32768;
Craig Tillera82950e2015-09-22 12:33:20 -0700818 server->request_freelist =
819 gpr_stack_lockfree_create(server->max_requested_calls);
820 for (i = 0; i < (size_t)server->max_requested_calls; i++) {
821 gpr_stack_lockfree_push(server->request_freelist, (int)i);
822 }
823 request_matcher_init(&server->unregistered_request_matcher,
824 server->max_requested_calls);
825 server->requested_calls = gpr_malloc(server->max_requested_calls *
826 sizeof(*server->requested_calls));
Craig Tiller729b35a2015-07-13 12:36:47 -0700827
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800828 /* Server filter stack is:
829
830 server_surface_filter - for making surface API calls
831 grpc_server_census_filter (optional) - for stats collection and tracing
832 {passed in filter stack}
833 grpc_connected_channel_filter - for interfacing with transports */
Bogdan Drutu441499a2016-01-26 19:16:04 -0800834 server->channel_filter_count = filter_count + 1u + (census_enabled ? 1u : 0u);
Craig Tillera82950e2015-09-22 12:33:20 -0700835 server->channel_filters =
836 gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800837 server->channel_filters[0] = &server_surface_filter;
Bogdan Drutu441499a2016-01-26 19:16:04 -0800838 if (census_enabled) {
Craig Tillera82950e2015-09-22 12:33:20 -0700839 server->channel_filters[1] = &grpc_server_census_filter;
840 }
841 for (i = 0; i < filter_count; i++) {
Bogdan Drutu441499a2016-01-26 19:16:04 -0800842 server->channel_filters[i + 1u + (census_enabled ? 1u : 0u)] = filters[i];
Craig Tillera82950e2015-09-22 12:33:20 -0700843 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800844
Craig Tillera82950e2015-09-22 12:33:20 -0700845 server->channel_args = grpc_channel_args_copy(args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800846
847 return server;
848}
849
Craig Tillera82950e2015-09-22 12:33:20 -0700850static int streq(const char *a, const char *b) {
851 if (a == NULL && b == NULL) return 1;
852 if (a == NULL) return 0;
853 if (b == NULL) return 0;
854 return 0 == strcmp(a, b);
Craig Tiller24be0f72015-02-10 14:04:22 -0800855}
856
Craig Tillera82950e2015-09-22 12:33:20 -0700857void *grpc_server_register_method(grpc_server *server, const char *method,
Craig Tiller5987c702016-03-09 16:55:23 -0800858 const char *host, uint32_t flags) {
Craig Tiller24be0f72015-02-10 14:04:22 -0800859 registered_method *m;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700860 GRPC_API_TRACE("grpc_server_register_method(server=%p, method=%s, host=%s)",
861 3, (server, method, host));
Craig Tillera82950e2015-09-22 12:33:20 -0700862 if (!method) {
863 gpr_log(GPR_ERROR,
864 "grpc_server_register_method method string cannot be NULL");
865 return NULL;
866 }
867 for (m = server->registered_methods; m; m = m->next) {
868 if (streq(m->method, method) && streq(m->host, host)) {
869 gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
870 host ? host : "*");
Craig Tiller24be0f72015-02-10 14:04:22 -0800871 return NULL;
872 }
Craig Tillera82950e2015-09-22 12:33:20 -0700873 }
874 m = gpr_malloc(sizeof(registered_method));
875 memset(m, 0, sizeof(*m));
876 request_matcher_init(&m->request_matcher, server->max_requested_calls);
877 m->method = gpr_strdup(method);
878 m->host = gpr_strdup(host);
Craig Tiller24be0f72015-02-10 14:04:22 -0800879 m->next = server->registered_methods;
880 server->registered_methods = m;
881 return m;
882}
883
Craig Tillera82950e2015-09-22 12:33:20 -0700884void grpc_server_start(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800885 listener *l;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800886 size_t i;
Craig Tillerf5768a62015-09-22 10:54:34 -0700887 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800888
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700889 GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
890
Craig Tillera82950e2015-09-22 12:33:20 -0700891 server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
892 for (i = 0; i < server->cq_count; i++) {
893 server->pollsets[i] = grpc_cq_pollset(server->cqs[i]);
894 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800895
Craig Tillera82950e2015-09-22 12:33:20 -0700896 for (l = server->listeners; l; l = l->next) {
897 l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count);
898 }
Craig Tillerdfff1b82015-09-21 14:39:57 -0700899
Craig Tillera82950e2015-09-22 12:33:20 -0700900 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800901}
902
Craig Tillera82950e2015-09-22 12:33:20 -0700903void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
904 grpc_transport *transport,
905 grpc_channel_filter const **extra_filters,
Craig Tillerb2b42612015-11-20 12:02:17 -0800906 size_t num_extra_filters,
Craig Tillera82950e2015-09-22 12:33:20 -0700907 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800908 size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700909 grpc_channel_filter const **filters =
910 gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800911 size_t i;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800912 size_t num_registered_methods;
913 size_t alloc;
914 registered_method *rm;
915 channel_registered_method *crm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800916 grpc_channel *channel;
917 channel_data *chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800918 grpc_mdstr *host;
919 grpc_mdstr *method;
Craig Tiller7536af02015-12-22 13:49:30 -0800920 uint32_t hash;
Craig Tillerf96dfc32015-09-10 14:43:18 -0700921 size_t slots;
Craig Tiller7536af02015-12-22 13:49:30 -0800922 uint32_t probes;
923 uint32_t max_probes = 0;
Craig Tillere039f032015-06-25 12:54:23 -0700924 grpc_transport_op op;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800925
Craig Tillera82950e2015-09-22 12:33:20 -0700926 for (i = 0; i < s->channel_filter_count; i++) {
927 filters[i] = s->channel_filters[i];
928 }
929 for (; i < s->channel_filter_count + num_extra_filters; i++) {
930 filters[i] = extra_filters[i - s->channel_filter_count];
931 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800932 filters[i] = &grpc_connected_channel_filter;
933
Craig Tillera82950e2015-09-22 12:33:20 -0700934 for (i = 0; i < s->cq_count; i++) {
935 memset(&op, 0, sizeof(op));
936 op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
937 grpc_transport_perform_op(exec_ctx, transport, &op);
938 }
ctillerd79b4862014-12-17 16:36:59 -0800939
Craig Tillera82950e2015-09-22 12:33:20 -0700940 channel = grpc_channel_create_from_filters(exec_ctx, NULL, filters,
Craig Tillerb2b42612015-11-20 12:02:17 -0800941 num_filters, args, 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700942 chand = (channel_data *)grpc_channel_stack_element(
Craig Tiller5987c702016-03-09 16:55:23 -0800943 grpc_channel_get_channel_stack(channel), 0)
944 ->channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800945 chand->server = s;
Craig Tillera82950e2015-09-22 12:33:20 -0700946 server_ref(s);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800947 chand->channel = channel;
948
Craig Tiller04cc8be2015-02-10 16:11:22 -0800949 num_registered_methods = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700950 for (rm = s->registered_methods; rm; rm = rm->next) {
951 num_registered_methods++;
952 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800953 /* build a lookup table phrased in terms of mdstr's in this channels context
954 to quickly find registered methods */
Craig Tillera82950e2015-09-22 12:33:20 -0700955 if (num_registered_methods > 0) {
956 slots = 2 * num_registered_methods;
957 alloc = sizeof(channel_registered_method) * slots;
958 chand->registered_methods = gpr_malloc(alloc);
959 memset(chand->registered_methods, 0, alloc);
960 for (rm = s->registered_methods; rm; rm = rm->next) {
Craig Tillerb2b42612015-11-20 12:02:17 -0800961 host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL;
962 method = grpc_mdstr_from_string(rm->method);
Craig Tillera82950e2015-09-22 12:33:20 -0700963 hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
964 for (probes = 0; chand->registered_methods[(hash + probes) % slots]
Craig Tiller5987c702016-03-09 16:55:23 -0800965 .server_registered_method != NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700966 probes++)
967 ;
968 if (probes > max_probes) max_probes = probes;
969 crm = &chand->registered_methods[(hash + probes) % slots];
970 crm->server_registered_method = rm;
971 crm->host = host;
972 crm->method = method;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800973 }
Craig Tiller7536af02015-12-22 13:49:30 -0800974 GPR_ASSERT(slots <= UINT32_MAX);
975 chand->registered_method_slots = (uint32_t)slots;
Craig Tillera82950e2015-09-22 12:33:20 -0700976 chand->registered_method_max_probes = max_probes;
977 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800978
Craig Tillera82950e2015-09-22 12:33:20 -0700979 grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
980 transport);
Craig Tiller7bd5ab12015-02-17 22:29:04 -0800981
Craig Tillera82950e2015-09-22 12:33:20 -0700982 gpr_mu_lock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800983 chand->next = &s->root_channel_data;
984 chand->prev = chand->next->prev;
985 chand->next->prev = chand->prev->next = chand;
Craig Tillera82950e2015-09-22 12:33:20 -0700986 gpr_mu_unlock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800987
Craig Tiller565b18b2015-09-23 10:09:42 -0700988 gpr_free((void *)filters);
Craig Tiller4b804102015-06-26 16:16:12 -0700989
Craig Tillera82950e2015-09-22 12:33:20 -0700990 GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity");
991 memset(&op, 0, sizeof(op));
Craig Tillerd7f12e32016-03-03 10:08:31 -0800992 op.set_accept_stream = true;
993 op.set_accept_stream_fn = accept_stream;
Craig Tiller4b804102015-06-26 16:16:12 -0700994 op.set_accept_stream_user_data = chand;
995 op.on_connectivity_state_change = &chand->channel_connectivity_changed;
996 op.connectivity_state = &chand->connectivity_state;
Craig Tillera82950e2015-09-22 12:33:20 -0700997 op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0;
998 grpc_transport_perform_op(exec_ctx, transport, &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800999}
1000
Craig Tillera82950e2015-09-22 12:33:20 -07001001void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg,
1002 grpc_cq_completion *storage) {
1003 (void)done_arg;
1004 gpr_free(storage);
murgatroid9900a3dab2015-08-19 11:15:38 -07001005}
1006
Craig Tillera82950e2015-09-22 12:33:20 -07001007static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s,
Craig Tiller6c396862016-01-28 13:53:40 -08001008 bool success) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001009 grpc_server *server = s;
Craig Tillera82950e2015-09-22 12:33:20 -07001010 gpr_mu_lock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001011 server->listeners_destroyed++;
Craig Tillera82950e2015-09-22 12:33:20 -07001012 maybe_finish_shutdown(exec_ctx, server);
1013 gpr_mu_unlock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001014}
1015
Craig Tillera82950e2015-09-22 12:33:20 -07001016void grpc_server_shutdown_and_notify(grpc_server *server,
1017 grpc_completion_queue *cq, void *tag) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001018 listener *l;
Craig Tillerbce999f2015-05-27 09:55:51 -07001019 shutdown_tag *sdt;
Craig Tillerff3ae682015-06-29 17:44:04 -07001020 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001021 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001022
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001023 GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3,
1024 (server, cq, tag));
1025
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001026 /* lock, and gather up some stuff to do */
Craig Tillera82950e2015-09-22 12:33:20 -07001027 gpr_mu_lock(&server->mu_global);
Craig Tiller4bf29282015-12-14 11:25:48 -08001028 grpc_cq_begin_op(cq, tag);
Craig Tillera82950e2015-09-22 12:33:20 -07001029 if (server->shutdown_published) {
1030 grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL,
1031 gpr_malloc(sizeof(grpc_cq_completion)));
1032 gpr_mu_unlock(&server->mu_global);
1033 goto done;
1034 }
1035 server->shutdown_tags =
1036 gpr_realloc(server->shutdown_tags,
1037 sizeof(shutdown_tag) * (server->num_shutdown_tags + 1));
Craig Tillerbce999f2015-05-27 09:55:51 -07001038 sdt = &server->shutdown_tags[server->num_shutdown_tags++];
1039 sdt->tag = tag;
1040 sdt->cq = cq;
Craig Tillera82950e2015-09-22 12:33:20 -07001041 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1042 gpr_mu_unlock(&server->mu_global);
1043 goto done;
1044 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001045
Craig Tillera82950e2015-09-22 12:33:20 -07001046 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
Craig Tillerab54f792015-07-08 08:34:20 -07001047
Craig Tillera82950e2015-09-22 12:33:20 -07001048 channel_broadcaster_init(server, &broadcaster);
nnoble0c475f02014-12-05 15:37:39 -08001049
Craig Tillerfc193e12015-09-24 15:29:03 -07001050 gpr_atm_rel_store(&server->shutdown_flag, 1);
1051
Craig Tillerbd217572015-02-11 18:10:56 -08001052 /* collect all unregistered then registered calls */
Craig Tillera82950e2015-09-22 12:33:20 -07001053 gpr_mu_lock(&server->mu_call);
1054 kill_pending_work_locked(&exec_ctx, server);
1055 gpr_mu_unlock(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001056
Craig Tillera82950e2015-09-22 12:33:20 -07001057 maybe_finish_shutdown(&exec_ctx, server);
1058 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001059
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001060 /* Shutdown listeners */
Craig Tillera82950e2015-09-22 12:33:20 -07001061 for (l = server->listeners; l; l = l->next) {
1062 grpc_closure_init(&l->destroy_done, listener_destroy_done, server);
1063 l->destroy(&exec_ctx, server, l->arg, &l->destroy_done);
1064 }
Craig Tillerff3ae682015-06-29 17:44:04 -07001065
Craig Tillera82950e2015-09-22 12:33:20 -07001066 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001067
Craig Tillerdfff1b82015-09-21 14:39:57 -07001068done:
Craig Tillera82950e2015-09-22 12:33:20 -07001069 grpc_exec_ctx_finish(&exec_ctx);
Craig Tilleraec96aa2015-04-07 14:32:15 -07001070}
1071
Craig Tillera82950e2015-09-22 12:33:20 -07001072void grpc_server_cancel_all_calls(grpc_server *server) {
Craig Tiller092d8d12015-07-04 22:35:00 -07001073 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001074 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillerafa2d632015-05-26 16:39:13 -07001075
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001076 GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server));
1077
Craig Tillera82950e2015-09-22 12:33:20 -07001078 gpr_mu_lock(&server->mu_global);
1079 channel_broadcaster_init(server, &broadcaster);
1080 gpr_mu_unlock(&server->mu_global);
Craig Tillerafa2d632015-05-26 16:39:13 -07001081
Craig Tillera82950e2015-09-22 12:33:20 -07001082 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1);
1083 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerafa2d632015-05-26 16:39:13 -07001084}
1085
Craig Tillera82950e2015-09-22 12:33:20 -07001086void grpc_server_destroy(grpc_server *server) {
Craig Tilleraec96aa2015-04-07 14:32:15 -07001087 listener *l;
Craig Tillerf5768a62015-09-22 10:54:34 -07001088 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller872af022015-04-24 15:57:52 -07001089
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001090 GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server));
1091
Craig Tillera82950e2015-09-22 12:33:20 -07001092 gpr_mu_lock(&server->mu_global);
1093 GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners);
1094 GPR_ASSERT(server->listeners_destroyed == num_listeners(server));
Craig Tilleraec96aa2015-04-07 14:32:15 -07001095
Craig Tillera82950e2015-09-22 12:33:20 -07001096 while (server->listeners) {
1097 l = server->listeners;
1098 server->listeners = l->next;
1099 gpr_free(l);
1100 }
Craig Tilleraec96aa2015-04-07 14:32:15 -07001101
Craig Tillera82950e2015-09-22 12:33:20 -07001102 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001103
Craig Tillera82950e2015-09-22 12:33:20 -07001104 server_unref(&exec_ctx, server);
1105 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001106}
1107
Craig Tillera82950e2015-09-22 12:33:20 -07001108void grpc_server_add_listener(
1109 grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1110 void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1111 grpc_pollset **pollsets, size_t pollset_count),
1112 void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1113 grpc_closure *on_done)) {
1114 listener *l = gpr_malloc(sizeof(listener));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001115 l->arg = arg;
1116 l->start = start;
1117 l->destroy = destroy;
1118 l->next = server->listeners;
1119 server->listeners = l;
1120}
1121
Craig Tillera82950e2015-09-22 12:33:20 -07001122static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1123 grpc_server *server,
1124 requested_call *rc) {
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001125 call_data *calld = NULL;
Craig Tillerb9d35962015-09-11 13:31:16 -07001126 request_matcher *rm = NULL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001127 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -07001128 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1129 fail_call(exec_ctx, server, rc);
1130 return GRPC_CALL_OK;
1131 }
1132 request_id = gpr_stack_lockfree_pop(server->request_freelist);
1133 if (request_id == -1) {
1134 /* out of request ids: just fail this one */
1135 fail_call(exec_ctx, server, rc);
1136 return GRPC_CALL_OK;
1137 }
1138 switch (rc->type) {
Craig Tiller04cc8be2015-02-10 16:11:22 -08001139 case BATCH_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001140 rm = &server->unregistered_request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001141 break;
1142 case REGISTERED_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001143 rm = &rc->data.registered.registered_method->request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001144 break;
Craig Tillera82950e2015-09-22 12:33:20 -07001145 }
Craig Tiller45724b32015-09-22 10:42:19 -07001146 server->requested_calls[request_id] = *rc;
Craig Tillera82950e2015-09-22 12:33:20 -07001147 gpr_free(rc);
Craig Tillerb9d35962015-09-11 13:31:16 -07001148 if (gpr_stack_lockfree_push(rm->requests, request_id)) {
Craig Tillera82950e2015-09-22 12:33:20 -07001149 /* this was the first queued request: we need to lock and start
1150 matching calls */
1151 gpr_mu_lock(&server->mu_call);
Craig Tillerb9d35962015-09-11 13:31:16 -07001152 while ((calld = rm->pending_head) != NULL) {
1153 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -07001154 if (request_id == -1) break;
Craig Tillerb9d35962015-09-11 13:31:16 -07001155 rm->pending_head = calld->pending_next;
Craig Tillera82950e2015-09-22 12:33:20 -07001156 gpr_mu_unlock(&server->mu_call);
1157 gpr_mu_lock(&calld->mu_state);
1158 if (calld->state == ZOMBIED) {
1159 gpr_mu_unlock(&calld->mu_state);
1160 grpc_closure_init(
1161 &calld->kill_zombie_closure, kill_zombie,
1162 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
Craig Tiller6c396862016-01-28 13:53:40 -08001163 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true,
1164 NULL);
Craig Tillera82950e2015-09-22 12:33:20 -07001165 } else {
1166 GPR_ASSERT(calld->state == PENDING);
1167 calld->state = ACTIVATED;
1168 gpr_mu_unlock(&calld->mu_state);
1169 begin_call(exec_ctx, server, calld,
1170 &server->requested_calls[request_id]);
1171 }
1172 gpr_mu_lock(&server->mu_call);
Craig Tiller45724b32015-09-22 10:42:19 -07001173 }
Craig Tillera82950e2015-09-22 12:33:20 -07001174 gpr_mu_unlock(&server->mu_call);
1175 }
Craig Tiller6a006ce2015-07-13 16:25:40 -07001176 return GRPC_CALL_OK;
Craig Tillercce17ac2015-01-20 09:29:28 -08001177}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001178
Craig Tillera82950e2015-09-22 12:33:20 -07001179grpc_call_error grpc_server_request_call(
1180 grpc_server *server, grpc_call **call, grpc_call_details *details,
1181 grpc_metadata_array *initial_metadata,
1182 grpc_completion_queue *cq_bound_to_call,
1183 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001184 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001185 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001186 requested_call *rc = gpr_malloc(sizeof(*rc));
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001187 GRPC_API_TRACE(
1188 "grpc_server_request_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001189 "server=%p, call=%p, details=%p, initial_metadata=%p, "
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001190 "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001191 7, (server, call, details, initial_metadata, cq_bound_to_call,
1192 cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001193 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1194 gpr_free(rc);
1195 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1196 goto done;
1197 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001198 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller9928d392015-08-18 09:40:24 -07001199 details->reserved = NULL;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001200 rc->type = BATCH_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001201 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001202 rc->tag = tag;
1203 rc->cq_bound_to_call = cq_bound_to_call;
1204 rc->cq_for_notification = cq_for_notification;
1205 rc->call = call;
1206 rc->data.batch.details = details;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001207 rc->initial_metadata = initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -07001208 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001209done:
Craig Tillera82950e2015-09-22 12:33:20 -07001210 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001211 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001212}
1213
Craig Tillera82950e2015-09-22 12:33:20 -07001214grpc_call_error grpc_server_request_registered_call(
Craig Tillerb9d35962015-09-11 13:31:16 -07001215 grpc_server *server, void *rmp, grpc_call **call, gpr_timespec *deadline,
Craig Tillera82950e2015-09-22 12:33:20 -07001216 grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload,
1217 grpc_completion_queue *cq_bound_to_call,
1218 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001219 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001220 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001221 requested_call *rc = gpr_malloc(sizeof(*rc));
Craig Tillerb9d35962015-09-11 13:31:16 -07001222 registered_method *rm = rmp;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001223 GRPC_API_TRACE(
1224 "grpc_server_request_registered_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001225 "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, "
1226 "optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
1227 "tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001228 9, (server, rmp, call, deadline, initial_metadata, optional_payload,
1229 cq_bound_to_call, cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001230 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1231 gpr_free(rc);
1232 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1233 goto done;
1234 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001235 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001236 rc->type = REGISTERED_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001237 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001238 rc->tag = tag;
1239 rc->cq_bound_to_call = cq_bound_to_call;
1240 rc->cq_for_notification = cq_for_notification;
1241 rc->call = call;
Craig Tillerb9d35962015-09-11 13:31:16 -07001242 rc->data.registered.registered_method = rm;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001243 rc->data.registered.deadline = deadline;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001244 rc->initial_metadata = initial_metadata;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001245 rc->data.registered.optional_payload = optional_payload;
Craig Tillera82950e2015-09-22 12:33:20 -07001246 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001247done:
Craig Tillera82950e2015-09-22 12:33:20 -07001248 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001249 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001250}
1251
Craig Tillera82950e2015-09-22 12:33:20 -07001252static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx,
Craig Tiller6c396862016-01-28 13:53:40 -08001253 void *user_data, bool success);
Craig Tiller24be0f72015-02-10 14:04:22 -08001254
Craig Tillera82950e2015-09-22 12:33:20 -07001255static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
Craig Tiller166e2502015-02-03 20:14:41 -08001256 gpr_slice slice = value->slice;
Craig Tillera82950e2015-09-22 12:33:20 -07001257 size_t len = GPR_SLICE_LENGTH(slice);
Craig Tiller166e2502015-02-03 20:14:41 -08001258
Craig Tillera82950e2015-09-22 12:33:20 -07001259 if (len + 1 > *capacity) {
1260 *capacity = GPR_MAX(len + 1, *capacity * 2);
1261 *dest = gpr_realloc(*dest, *capacity);
1262 }
1263 memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
Craig Tiller166e2502015-02-03 20:14:41 -08001264}
1265
Craig Tillera82950e2015-09-22 12:33:20 -07001266static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1267 call_data *calld, requested_call *rc) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001268 grpc_op ops[1];
1269 grpc_op *op = ops;
1270
1271 memset(ops, 0, sizeof(ops));
Craig Tiller24be0f72015-02-10 14:04:22 -08001272
1273 /* called once initial metadata has been read by the call, but BEFORE
1274 the ioreq to fetch it out of the call has been executed.
1275 This means metadata related fields can be relied on in calld, but to
1276 fill in the metadata array passed by the client, we need to perform
1277 an ioreq op, that should complete immediately. */
1278
Craig Tillera82950e2015-09-22 12:33:20 -07001279 grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001280 grpc_closure_init(&rc->publish, publish_registered_or_batch, rc);
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001281 *rc->call = calld->call;
1282 calld->cq_new = rc->cq_for_notification;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001283 GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
Craig Tillera82950e2015-09-22 12:33:20 -07001284 switch (rc->type) {
Craig Tiller24be0f72015-02-10 14:04:22 -08001285 case BATCH_CALL:
Craig Tillera82950e2015-09-22 12:33:20 -07001286 GPR_ASSERT(calld->host != NULL);
1287 GPR_ASSERT(calld->path != NULL);
1288 cpstr(&rc->data.batch.details->host,
1289 &rc->data.batch.details->host_capacity, calld->host);
1290 cpstr(&rc->data.batch.details->method,
1291 &rc->data.batch.details->method_capacity, calld->path);
Masood Malekghassemibf177c82015-04-27 12:14:38 -07001292 rc->data.batch.details->deadline = calld->deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -08001293 break;
1294 case REGISTERED_CALL:
1295 *rc->data.registered.deadline = calld->deadline;
Craig Tillera82950e2015-09-22 12:33:20 -07001296 if (rc->data.registered.optional_payload) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001297 op->op = GRPC_OP_RECV_MESSAGE;
1298 op->data.recv_message = rc->data.registered.optional_payload;
1299 op++;
Craig Tillera82950e2015-09-22 12:33:20 -07001300 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001301 break;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001302 default:
1303 GPR_UNREACHABLE_CODE(return );
Craig Tillera82950e2015-09-22 12:33:20 -07001304 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001305
Craig Tillera82950e2015-09-22 12:33:20 -07001306 GRPC_CALL_INTERNAL_REF(calld->call, "server");
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001307 grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops,
1308 (size_t)(op - ops), &rc->publish);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001309}
1310
Craig Tillera82950e2015-09-22 12:33:20 -07001311static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
1312 grpc_cq_completion *c) {
Craig Tiller6a006ce2015-07-13 16:25:40 -07001313 requested_call *rc = req;
1314 grpc_server *server = rc->server;
1315
Craig Tillera82950e2015-09-22 12:33:20 -07001316 if (rc >= server->requested_calls &&
1317 rc < server->requested_calls + server->max_requested_calls) {
1318 GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
1319 gpr_stack_lockfree_push(server->request_freelist,
1320 (int)(rc - server->requested_calls));
1321 } else {
1322 gpr_free(req);
1323 }
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001324
Craig Tillera82950e2015-09-22 12:33:20 -07001325 server_unref(exec_ctx, server);
Craig Tiller24be0f72015-02-10 14:04:22 -08001326}
1327
Craig Tillera82950e2015-09-22 12:33:20 -07001328static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1329 requested_call *rc) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001330 *rc->call = NULL;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001331 rc->initial_metadata->count = 0;
1332
Craig Tillera82950e2015-09-22 12:33:20 -07001333 server_ref(server);
1334 grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
1335 done_request_event, rc, &rc->completion);
Craig Tiller24be0f72015-02-10 14:04:22 -08001336}
1337
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001338static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc,
Craig Tiller6c396862016-01-28 13:53:40 -08001339 bool success) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001340 requested_call *rc = prc;
1341 grpc_call *call = *rc->call;
Craig Tillera82950e2015-09-22 12:33:20 -07001342 grpc_call_element *elem =
1343 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
Craig Tiller20bc56d2015-02-12 09:02:56 -08001344 call_data *calld = elem->call_data;
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001345 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001346 server_ref(chand->server);
1347 grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event,
1348 rc, &rc->completion);
1349 GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server");
Craig Tiller24be0f72015-02-10 14:04:22 -08001350}
1351
Craig Tillera82950e2015-09-22 12:33:20 -07001352const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001353 return server->channel_args;
Craig Tiller190d3602015-02-18 09:23:38 -08001354}
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001355
Craig Tillera82950e2015-09-22 12:33:20 -07001356int grpc_server_has_open_connections(grpc_server *server) {
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001357 int r;
Craig Tillera82950e2015-09-22 12:33:20 -07001358 gpr_mu_lock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001359 r = server->root_channel_data.next != &server->root_channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001360 gpr_mu_unlock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001361 return r;
1362}