blob: 1e1cde3648a4b6921e66fceb88fb067e8e0d5f45 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, 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;
116 gpr_uint32 registered_method_slots;
117 gpr_uint32 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;
156 grpc_metadata_array initial_metadata;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700157
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800158 grpc_closure got_initial_metadata;
159 grpc_closure server_on_recv_initial_metadata;
Craig Tiller33825112015-09-18 07:44:19 -0700160 grpc_closure kill_zombie_closure;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800161 grpc_closure *on_done_recv_initial_metadata;
David Garcia Quintas284488b2015-05-28 16:27:39 -0700162
Craig Tiller729b35a2015-07-13 12:36:47 -0700163 call_data *pending_next;
164};
165
Craig Tillera82950e2015-09-22 12:33:20 -0700166struct request_matcher {
Craig Tiller729b35a2015-07-13 12:36:47 -0700167 call_data *pending_head;
168 call_data *pending_tail;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700169 gpr_stack_lockfree *requests;
Craig Tiller729b35a2015-07-13 12:36:47 -0700170};
171
Craig Tillera82950e2015-09-22 12:33:20 -0700172struct registered_method {
Craig Tiller729b35a2015-07-13 12:36:47 -0700173 char *method;
174 char *host;
175 request_matcher request_matcher;
176 registered_method *next;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800177};
178
Craig Tillera82950e2015-09-22 12:33:20 -0700179typedef struct {
Craig Tillerff3ae682015-06-29 17:44:04 -0700180 grpc_channel **channels;
181 size_t num_channels;
182} channel_broadcaster;
183
Craig Tillera82950e2015-09-22 12:33:20 -0700184struct grpc_server {
Craig Tiller729b35a2015-07-13 12:36:47 -0700185 size_t channel_filter_count;
Craig Tiller565b18b2015-09-23 10:09:42 -0700186 grpc_channel_filter const **channel_filters;
Craig Tiller729b35a2015-07-13 12:36:47 -0700187 grpc_channel_args *channel_args;
188
189 grpc_completion_queue **cqs;
190 grpc_pollset **pollsets;
191 size_t cq_count;
192
193 /* The two following mutexes control access to server-state
194 mu_global controls access to non-call-related state (e.g., channel state)
195 mu_call controls access to call-related state (e.g., the call lists)
196
197 If they are ever required to be nested, you must lock mu_global
198 before mu_call. This is currently used in shutdown processing
199 (grpc_server_shutdown_and_notify and maybe_finish_shutdown) */
Craig Tillera82950e2015-09-22 12:33:20 -0700200 gpr_mu mu_global; /* mutex for server and channel state */
201 gpr_mu mu_call; /* mutex for call-specific state */
Craig Tiller729b35a2015-07-13 12:36:47 -0700202
203 registered_method *registered_methods;
204 request_matcher unregistered_request_matcher;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700205 /** free list of available requested_calls indices */
206 gpr_stack_lockfree *request_freelist;
207 /** requested call backing data */
208 requested_call *requested_calls;
Craig Tiller32ca48c2015-09-10 11:47:15 -0700209 size_t max_requested_calls;
Craig Tiller729b35a2015-07-13 12:36:47 -0700210
Craig Tiller6a006ce2015-07-13 16:25:40 -0700211 gpr_atm shutdown_flag;
Craig Tiller729b35a2015-07-13 12:36:47 -0700212 gpr_uint8 shutdown_published;
213 size_t num_shutdown_tags;
214 shutdown_tag *shutdown_tags;
215
216 channel_data root_channel_data;
217
218 listener *listeners;
219 int listeners_destroyed;
220 gpr_refcount internal_refcount;
221
222 /** when did we print the last shutdown progress message */
223 gpr_timespec last_shutdown_message_time;
224};
225
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800226#define SERVER_FROM_CALL_ELEM(elem) \
227 (((channel_data *)(elem)->channel_data)->server)
228
Craig Tillera82950e2015-09-22 12:33:20 -0700229static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
230 call_data *calld, requested_call *rc);
231static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
232 requested_call *rc);
Vijay Pai8931cdd2015-06-17 12:42:17 -0700233/* Before calling maybe_finish_shutdown, we must hold mu_global and not
234 hold mu_call */
Craig Tillera82950e2015-09-22 12:33:20 -0700235static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server);
Craig Tiller24be0f72015-02-10 14:04:22 -0800236
Craig Tiller729b35a2015-07-13 12:36:47 -0700237/*
238 * channel broadcaster
239 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700240
241/* assumes server locked */
Craig Tillera82950e2015-09-22 12:33:20 -0700242static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700243 channel_data *c;
244 size_t count = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700245 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
246 count++;
247 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700248 cb->num_channels = count;
Craig Tillera82950e2015-09-22 12:33:20 -0700249 cb->channels = gpr_malloc(sizeof(*cb->channels) * cb->num_channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700250 count = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700251 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
252 cb->channels[count++] = c->channel;
253 GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast");
254 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700255}
256
Craig Tillera82950e2015-09-22 12:33:20 -0700257struct shutdown_cleanup_args {
Craig Tiller33825112015-09-18 07:44:19 -0700258 grpc_closure closure;
Craig Tillerff3ae682015-06-29 17:44:04 -0700259 gpr_slice slice;
260};
261
Craig Tillera82950e2015-09-22 12:33:20 -0700262static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
263 int iomgr_status_ignored) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700264 struct shutdown_cleanup_args *a = arg;
Craig Tillera82950e2015-09-22 12:33:20 -0700265 gpr_slice_unref(a->slice);
266 gpr_free(a);
Craig Tillerff3ae682015-06-29 17:44:04 -0700267}
268
Craig Tillera82950e2015-09-22 12:33:20 -0700269static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
270 int send_goaway, int send_disconnect) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700271 grpc_transport_op op;
272 struct shutdown_cleanup_args *sc;
273 grpc_channel_element *elem;
274
Craig Tillera82950e2015-09-22 12:33:20 -0700275 memset(&op, 0, sizeof(op));
Craig Tillerff3ae682015-06-29 17:44:04 -0700276 op.send_goaway = send_goaway;
Craig Tillera82950e2015-09-22 12:33:20 -0700277 sc = gpr_malloc(sizeof(*sc));
278 sc->slice = gpr_slice_from_copied_string("Server shutdown");
Craig Tillerff3ae682015-06-29 17:44:04 -0700279 op.goaway_message = &sc->slice;
280 op.goaway_status = GRPC_STATUS_OK;
281 op.disconnect = send_disconnect;
Craig Tillera82950e2015-09-22 12:33:20 -0700282 grpc_closure_init(&sc->closure, shutdown_cleanup, sc);
Craig Tillerff3ae682015-06-29 17:44:04 -0700283 op.on_consumed = &sc->closure;
284
Craig Tillera82950e2015-09-22 12:33:20 -0700285 elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
286 elem->filter->start_transport_op(exec_ctx, elem, &op);
Craig Tillerff3ae682015-06-29 17:44:04 -0700287}
288
Craig Tillera82950e2015-09-22 12:33:20 -0700289static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx,
290 channel_broadcaster *cb,
291 int send_goaway,
292 int force_disconnect) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700293 size_t i;
294
Craig Tillera82950e2015-09-22 12:33:20 -0700295 for (i = 0; i < cb->num_channels; i++) {
296 send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect);
297 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast");
298 }
299 gpr_free(cb->channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700300}
301
Craig Tiller729b35a2015-07-13 12:36:47 -0700302/*
303 * request_matcher
304 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700305
Craig Tiller8dc09712015-09-24 13:58:16 -0700306static void request_matcher_init(request_matcher *rm, size_t entries) {
Craig Tillerb9d35962015-09-11 13:31:16 -0700307 memset(rm, 0, sizeof(*rm));
308 rm->requests = gpr_stack_lockfree_create(entries);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800309}
310
Craig Tillerb9d35962015-09-11 13:31:16 -0700311static void request_matcher_destroy(request_matcher *rm) {
312 GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests) == -1);
313 gpr_stack_lockfree_destroy(rm->requests);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800314}
315
Craig Tillera82950e2015-09-22 12:33:20 -0700316static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, int success) {
317 grpc_call_destroy(grpc_call_from_top_element(elem));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800318}
319
Craig Tiller8dc09712015-09-24 13:58:16 -0700320static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx,
321 request_matcher *rm) {
Craig Tillerb9d35962015-09-11 13:31:16 -0700322 while (rm->pending_head) {
323 call_data *calld = rm->pending_head;
324 rm->pending_head = calld->pending_next;
Craig Tillera82950e2015-09-22 12:33:20 -0700325 gpr_mu_lock(&calld->mu_state);
326 calld->state = ZOMBIED;
327 gpr_mu_unlock(&calld->mu_state);
328 grpc_closure_init(
329 &calld->kill_zombie_closure, kill_zombie,
330 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
331 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
332 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800333}
334
Craig Tillera82950e2015-09-22 12:33:20 -0700335static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx,
336 grpc_server *server,
337 request_matcher *rm) {
Craig Tiller1191e212015-07-30 14:49:02 -0700338 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -0700339 while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) {
340 fail_call(exec_ctx, server, &server->requested_calls[request_id]);
341 }
Craig Tiller1191e212015-07-30 14:49:02 -0700342}
343
Craig Tiller729b35a2015-07-13 12:36:47 -0700344/*
345 * server proper
346 */
347
Craig Tillera82950e2015-09-22 12:33:20 -0700348static void server_ref(grpc_server *server) {
349 gpr_ref(&server->internal_refcount);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800350}
351
Craig Tillera82950e2015-09-22 12:33:20 -0700352static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800353 registered_method *rm;
Craig Tiller89504612015-04-27 11:48:46 -0700354 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700355 grpc_channel_args_destroy(server->channel_args);
356 gpr_mu_destroy(&server->mu_global);
357 gpr_mu_destroy(&server->mu_call);
Craig Tiller565b18b2015-09-23 10:09:42 -0700358 gpr_free((void *)server->channel_filters);
Craig Tillera82950e2015-09-22 12:33:20 -0700359 while ((rm = server->registered_methods) != NULL) {
360 server->registered_methods = rm->next;
361 request_matcher_destroy(&rm->request_matcher);
362 gpr_free(rm->method);
363 gpr_free(rm->host);
364 gpr_free(rm);
365 }
366 for (i = 0; i < server->cq_count; i++) {
367 GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server");
368 }
369 request_matcher_destroy(&server->unregistered_request_matcher);
370 gpr_stack_lockfree_destroy(server->request_freelist);
371 gpr_free(server->cqs);
372 gpr_free(server->pollsets);
373 gpr_free(server->shutdown_tags);
374 gpr_free(server->requested_calls);
375 gpr_free(server);
Craig Tilleree945e82015-05-26 16:15:34 -0700376}
377
Craig Tillera82950e2015-09-22 12:33:20 -0700378static void server_unref(grpc_exec_ctx *exec_ctx, grpc_server *server) {
379 if (gpr_unref(&server->internal_refcount)) {
380 server_delete(exec_ctx, server);
381 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800382}
383
Craig Tillera82950e2015-09-22 12:33:20 -0700384static int is_channel_orphaned(channel_data *chand) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800385 return chand->next == chand;
386}
387
Craig Tillera82950e2015-09-22 12:33:20 -0700388static void orphan_channel(channel_data *chand) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800389 chand->next->prev = chand->prev;
390 chand->prev->next = chand->next;
391 chand->next = chand->prev = chand;
392}
393
Craig Tillera82950e2015-09-22 12:33:20 -0700394static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd,
395 int success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800396 channel_data *chand = cd;
397 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700398 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server");
399 server_unref(exec_ctx, server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800400}
401
Craig Tillera82950e2015-09-22 12:33:20 -0700402static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) {
403 if (is_channel_orphaned(chand)) return;
404 GPR_ASSERT(chand->server != NULL);
405 orphan_channel(chand);
406 server_ref(chand->server);
407 maybe_finish_shutdown(exec_ctx, chand->server);
David Garcia Quintas284488b2015-05-28 16:27:39 -0700408 chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
409 chand->finish_destroy_channel_closure.cb_arg = chand;
Craig Tillera82950e2015-09-22 12:33:20 -0700410 grpc_exec_ctx_enqueue(exec_ctx, &chand->finish_destroy_channel_closure, 1);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800411}
412
Craig Tillera82950e2015-09-22 12:33:20 -0700413static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server,
Craig Tiller8dc09712015-09-24 13:58:16 -0700414 grpc_call_element *elem, request_matcher *rm) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800415 call_data *calld = elem->call_data;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700416 int request_id;
417
Craig Tillera82950e2015-09-22 12:33:20 -0700418 if (gpr_atm_acq_load(&server->shutdown_flag)) {
419 gpr_mu_lock(&calld->mu_state);
420 calld->state = ZOMBIED;
421 gpr_mu_unlock(&calld->mu_state);
422 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
423 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
424 return;
425 }
Craig Tiller45724b32015-09-22 10:42:19 -0700426
Craig Tillerb9d35962015-09-11 13:31:16 -0700427 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -0700428 if (request_id == -1) {
429 gpr_mu_lock(&server->mu_call);
430 gpr_mu_lock(&calld->mu_state);
431 calld->state = PENDING;
432 gpr_mu_unlock(&calld->mu_state);
Craig Tillerb9d35962015-09-11 13:31:16 -0700433 if (rm->pending_head == NULL) {
434 rm->pending_tail = rm->pending_head = calld;
Craig Tillera82950e2015-09-22 12:33:20 -0700435 } else {
Craig Tillerb9d35962015-09-11 13:31:16 -0700436 rm->pending_tail->pending_next = calld;
437 rm->pending_tail = calld;
Craig Tiller45724b32015-09-22 10:42:19 -0700438 }
Craig Tillera82950e2015-09-22 12:33:20 -0700439 calld->pending_next = NULL;
440 gpr_mu_unlock(&server->mu_call);
441 } else {
442 gpr_mu_lock(&calld->mu_state);
443 calld->state = ACTIVATED;
444 gpr_mu_unlock(&calld->mu_state);
445 begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
446 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800447}
448
Craig Tillera82950e2015-09-22 12:33:20 -0700449static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800450 channel_data *chand = elem->channel_data;
451 call_data *calld = elem->call_data;
452 grpc_server *server = chand->server;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800453 gpr_uint32 i;
454 gpr_uint32 hash;
455 channel_registered_method *rm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800456
Craig Tillera82950e2015-09-22 12:33:20 -0700457 if (chand->registered_methods && calld->path && calld->host) {
458 /* TODO(ctiller): unify these two searches */
459 /* check for an exact match with host */
460 hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
461 for (i = 0; i <= chand->registered_method_max_probes; i++) {
462 rm = &chand->registered_methods[(hash + i) %
463 chand->registered_method_slots];
464 if (!rm) break;
465 if (rm->host != calld->host) continue;
466 if (rm->method != calld->path) continue;
467 finish_start_new_rpc(exec_ctx, server, elem,
468 &rm->server_registered_method->request_matcher);
469 return;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800470 }
Craig Tillera82950e2015-09-22 12:33:20 -0700471 /* check for a wildcard method definition (no host set) */
472 hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
473 for (i = 0; i <= chand->registered_method_max_probes; i++) {
474 rm = &chand->registered_methods[(hash + i) %
475 chand->registered_method_slots];
476 if (!rm) break;
477 if (rm->host != NULL) continue;
478 if (rm->method != calld->path) continue;
479 finish_start_new_rpc(exec_ctx, server, elem,
480 &rm->server_registered_method->request_matcher);
481 return;
482 }
483 }
484 finish_start_new_rpc(exec_ctx, server, elem,
485 &server->unregistered_request_matcher);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800486}
487
Craig Tillera82950e2015-09-22 12:33:20 -0700488static int num_listeners(grpc_server *server) {
Craig Tilleree945e82015-05-26 16:15:34 -0700489 listener *l;
490 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700491 for (l = server->listeners; l; l = l->next) {
492 n++;
493 }
Craig Tilleree945e82015-05-26 16:15:34 -0700494 return n;
495}
496
Craig Tillera82950e2015-09-22 12:33:20 -0700497static void done_shutdown_event(grpc_exec_ctx *exec_ctx, void *server,
498 grpc_cq_completion *completion) {
499 server_unref(exec_ctx, server);
Craig Tiller97fc6a32015-07-08 15:31:35 -0700500}
501
Craig Tillera82950e2015-09-22 12:33:20 -0700502static int num_channels(grpc_server *server) {
Craig Tillerab54f792015-07-08 08:34:20 -0700503 channel_data *chand;
504 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700505 for (chand = server->root_channel_data.next;
506 chand != &server->root_channel_data; chand = chand->next) {
507 n++;
508 }
Craig Tillerab54f792015-07-08 08:34:20 -0700509 return n;
510}
511
Craig Tillera82950e2015-09-22 12:33:20 -0700512static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx,
513 grpc_server *server) {
Craig Tiller1191e212015-07-30 14:49:02 -0700514 registered_method *rm;
Craig Tillera82950e2015-09-22 12:33:20 -0700515 request_matcher_kill_requests(exec_ctx, server,
516 &server->unregistered_request_matcher);
517 request_matcher_zombify_all_pending_calls(
518 exec_ctx, &server->unregistered_request_matcher);
519 for (rm = server->registered_methods; rm; rm = rm->next) {
520 request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher);
521 request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
522 }
Craig Tillerdc627722015-05-26 15:27:02 -0700523}
524
Craig Tillera82950e2015-09-22 12:33:20 -0700525static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
526 grpc_server *server) {
Craig Tiller45724b32015-09-22 10:42:19 -0700527 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700528 if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) {
529 return;
530 }
Craig Tiller45724b32015-09-22 10:42:19 -0700531
Craig Tillera82950e2015-09-22 12:33:20 -0700532 kill_pending_work_locked(exec_ctx, server);
Craig Tiller45724b32015-09-22 10:42:19 -0700533
Craig Tillera82950e2015-09-22 12:33:20 -0700534 if (server->root_channel_data.next != &server->root_channel_data ||
535 server->listeners_destroyed < num_listeners(server)) {
536 if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
537 server->last_shutdown_message_time),
538 gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
539 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
540 gpr_log(GPR_DEBUG,
541 "Waiting for %d channels and %d/%d listeners to be destroyed"
542 " before shutting down server",
543 num_channels(server),
544 num_listeners(server) - server->listeners_destroyed,
545 num_listeners(server));
Craig Tiller45724b32015-09-22 10:42:19 -0700546 }
Craig Tillera82950e2015-09-22 12:33:20 -0700547 return;
548 }
Craig Tiller45724b32015-09-22 10:42:19 -0700549 server->shutdown_published = 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700550 for (i = 0; i < server->num_shutdown_tags; i++) {
551 server_ref(server);
552 grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq,
553 server->shutdown_tags[i].tag, 1, done_shutdown_event, server,
554 &server->shutdown_tags[i].completion);
555 }
Craig Tiller45724b32015-09-22 10:42:19 -0700556}
557
Craig Tillera82950e2015-09-22 12:33:20 -0700558static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
Craig Tiller6902ad22015-04-16 08:01:49 -0700559 grpc_call_element *elem = user_data;
Craig Tillercce17ac2015-01-20 09:29:28 -0800560 call_data *calld = elem->call_data;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800561 if (md->key == GRPC_MDSTR_PATH) {
Craig Tillera82950e2015-09-22 12:33:20 -0700562 calld->path = GRPC_MDSTR_REF(md->value);
563 return NULL;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800564 } else if (md->key == GRPC_MDSTR_AUTHORITY) {
Craig Tillera82950e2015-09-22 12:33:20 -0700565 calld->host = GRPC_MDSTR_REF(md->value);
566 return NULL;
567 }
Craig Tiller6902ad22015-04-16 08:01:49 -0700568 return md;
569}
570
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800571static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
572 int success) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700573 grpc_call_element *elem = ptr;
Craig Tiller6902ad22015-04-16 08:01:49 -0700574 call_data *calld = elem->call_data;
Craig Tiller94329d02015-07-23 09:52:11 -0700575 gpr_timespec op_deadline;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700576
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800577 grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
578 op_deadline = calld->recv_initial_metadata->deadline;
579 if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
580 calld->deadline = op_deadline;
581 }
582 if (calld->host && calld->path) {
583 /* do nothing */
584 } else {
585 success = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700586 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700587
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800588 calld->on_done_recv_initial_metadata->cb(
589 exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success);
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700590}
591
Craig Tillera82950e2015-09-22 12:33:20 -0700592static void server_mutate_op(grpc_call_element *elem,
593 grpc_transport_stream_op *op) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700594 call_data *calld = elem->call_data;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700595
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800596 if (op->recv_initial_metadata != NULL) {
597 calld->recv_initial_metadata = op->recv_initial_metadata;
598 calld->on_done_recv_initial_metadata = op->on_complete;
599 op->on_complete = &calld->server_on_recv_initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -0700600 }
Craig Tiller50d9db52015-04-23 10:52:14 -0700601}
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700602
Craig Tillera82950e2015-09-22 12:33:20 -0700603static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
604 grpc_call_element *elem,
605 grpc_transport_stream_op *op) {
606 GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
607 server_mutate_op(elem, op);
608 grpc_call_next_op(exec_ctx, elem, op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800609}
610
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800611static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
612 int success) {
613 grpc_call_element *elem = ptr;
614 call_data *calld = elem->call_data;
615 if (success) {
616 start_new_rpc(exec_ctx, elem);
617 } else {
618 gpr_mu_lock(&calld->mu_state);
619 if (calld->state == NOT_STARTED) {
620 calld->state = ZOMBIED;
621 gpr_mu_unlock(&calld->mu_state);
622 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
623 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
624 } else if (calld->state == PENDING) {
625 calld->state = ZOMBIED;
626 gpr_mu_unlock(&calld->mu_state);
627 /* zombied call will be destroyed when it's removed from the pending
628 queue... later */
629 } else {
630 gpr_mu_unlock(&calld->mu_state);
631 }
632 }
633}
634
635static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
636 grpc_transport *transport,
Craig Tillera82950e2015-09-22 12:33:20 -0700637 const void *transport_server_data) {
Craig Tillere039f032015-06-25 12:54:23 -0700638 channel_data *chand = cd;
639 /* create a call */
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800640 grpc_call *call =
641 grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data,
642 NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
643 grpc_call_element *elem =
644 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
645 call_data *calld = elem->call_data;
646 grpc_op op;
647 memset(&op, 0, sizeof(op));
648 op.op = GRPC_OP_RECV_INITIAL_METADATA;
649 op.data.recv_initial_metadata = &calld->initial_metadata;
650 grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem);
651 grpc_call_start_batch_and_execute(exec_ctx, call, &op, 1,
652 &calld->got_initial_metadata);
Craig Tillere039f032015-06-25 12:54:23 -0700653}
654
Craig Tillera82950e2015-09-22 12:33:20 -0700655static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd,
656 int iomgr_status_ignored) {
Craig Tillere039f032015-06-25 12:54:23 -0700657 channel_data *chand = cd;
658 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700659 if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
660 grpc_transport_op op;
661 memset(&op, 0, sizeof(op));
662 op.on_connectivity_state_change = &chand->channel_connectivity_changed,
663 op.connectivity_state = &chand->connectivity_state;
664 grpc_channel_next_op(exec_ctx,
665 grpc_channel_stack_element(
666 grpc_channel_get_channel_stack(chand->channel), 0),
667 &op);
668 } else {
669 gpr_mu_lock(&server->mu_global);
670 destroy_channel(exec_ctx, chand);
671 gpr_mu_unlock(&server->mu_global);
672 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity");
673 }
Craig Tillere039f032015-06-25 12:54:23 -0700674}
675
Craig Tillera82950e2015-09-22 12:33:20 -0700676static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800677 grpc_call_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800678 call_data *calld = elem->call_data;
679 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700680 memset(calld, 0, sizeof(call_data));
681 calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
682 calld->call = grpc_call_from_top_element(elem);
683 gpr_mu_init(&calld->mu_state);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800684
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800685 grpc_closure_init(&calld->server_on_recv_initial_metadata,
686 server_on_recv_initial_metadata, elem);
Craig Tiller1e6facb2015-06-11 22:47:11 -0700687
Craig Tillera82950e2015-09-22 12:33:20 -0700688 server_ref(chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800689}
690
Craig Tillera82950e2015-09-22 12:33:20 -0700691static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
692 grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800693 channel_data *chand = elem->channel_data;
Craig Tillerdb7db992015-01-29 11:19:01 -0800694 call_data *calld = elem->call_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800695
Craig Tillera82950e2015-09-22 12:33:20 -0700696 GPR_ASSERT(calld->state != PENDING);
Craig Tiller092d8d12015-07-04 22:35:00 -0700697
Craig Tillera82950e2015-09-22 12:33:20 -0700698 if (calld->host) {
699 GRPC_MDSTR_UNREF(calld->host);
700 }
701 if (calld->path) {
702 GRPC_MDSTR_UNREF(calld->path);
703 }
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800704 grpc_metadata_array_destroy(&calld->initial_metadata);
Craig Tiller4df31a62015-01-30 09:44:31 -0800705
Craig Tillera82950e2015-09-22 12:33:20 -0700706 gpr_mu_destroy(&calld->mu_state);
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700707
Craig Tillera82950e2015-09-22 12:33:20 -0700708 server_unref(exec_ctx, chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800709}
710
Craig Tillera82950e2015-09-22 12:33:20 -0700711static void init_channel_elem(grpc_exec_ctx *exec_ctx,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800712 grpc_channel_element *elem,
713 grpc_channel_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800714 channel_data *chand = elem->channel_data;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800715 GPR_ASSERT(args->is_first);
716 GPR_ASSERT(!args->is_last);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800717 chand->server = NULL;
718 chand->channel = NULL;
719 chand->next = chand->prev = chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800720 chand->registered_methods = NULL;
Craig Tillere039f032015-06-25 12:54:23 -0700721 chand->connectivity_state = GRPC_CHANNEL_IDLE;
Craig Tillera82950e2015-09-22 12:33:20 -0700722 grpc_closure_init(&chand->channel_connectivity_changed,
723 channel_connectivity_changed, chand);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800724}
725
Craig Tillera82950e2015-09-22 12:33:20 -0700726static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
727 grpc_channel_element *elem) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800728 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800729 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700730 if (chand->registered_methods) {
731 for (i = 0; i < chand->registered_method_slots; i++) {
732 if (chand->registered_methods[i].method) {
733 GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
734 }
735 if (chand->registered_methods[i].host) {
736 GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
737 }
Craig Tillerec3257c2015-02-12 15:59:43 -0800738 }
Craig Tillera82950e2015-09-22 12:33:20 -0700739 gpr_free(chand->registered_methods);
740 }
741 if (chand->server) {
742 gpr_mu_lock(&chand->server->mu_global);
743 chand->next->prev = chand->prev;
744 chand->prev->next = chand->next;
745 chand->next = chand->prev = chand;
746 maybe_finish_shutdown(exec_ctx, chand->server);
747 gpr_mu_unlock(&chand->server->mu_global);
Craig Tillera82950e2015-09-22 12:33:20 -0700748 server_unref(exec_ctx, chand->server);
749 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800750}
751
752static const grpc_channel_filter server_surface_filter = {
Craig Tiller71a0f9d2015-09-28 17:22:01 -0700753 server_start_transport_stream_op, grpc_channel_next_op, sizeof(call_data),
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800754 init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem,
755 sizeof(channel_data), init_channel_elem, destroy_channel_elem,
756 grpc_call_next_get_peer, "server",
Craig Tiller9f28ac22015-01-27 17:01:29 -0800757};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800758
Craig Tillera82950e2015-09-22 12:33:20 -0700759void grpc_server_register_completion_queue(grpc_server *server,
760 grpc_completion_queue *cq,
761 void *reserved) {
Craig Tiller20bc56d2015-02-12 09:02:56 -0800762 size_t i, n;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700763 GRPC_API_TRACE(
764 "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
765 (server, cq, reserved));
Craig Tillera82950e2015-09-22 12:33:20 -0700766 GPR_ASSERT(!reserved);
767 for (i = 0; i < server->cq_count; i++) {
768 if (server->cqs[i] == cq) return;
769 }
770 GRPC_CQ_INTERNAL_REF(cq, "server");
771 grpc_cq_mark_server_cq(cq);
Craig Tiller20bc56d2015-02-12 09:02:56 -0800772 n = server->cq_count++;
Craig Tillera82950e2015-09-22 12:33:20 -0700773 server->cqs = gpr_realloc(server->cqs,
774 server->cq_count * sizeof(grpc_completion_queue *));
Craig Tiller20bc56d2015-02-12 09:02:56 -0800775 server->cqs[n] = cq;
776}
777
Craig Tillera82950e2015-09-22 12:33:20 -0700778grpc_server *grpc_server_create_from_filters(
779 const grpc_channel_filter **filters, size_t filter_count,
780 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800781 size_t i;
Alistair Veitch9d48ebf2015-06-01 10:01:03 -0700782 /* TODO(census): restore this once we finalize census filter etc.
783 int census_enabled = grpc_channel_args_is_census_enabled(args); */
784 int census_enabled = 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800785
Craig Tillera82950e2015-09-22 12:33:20 -0700786 grpc_server *server = gpr_malloc(sizeof(grpc_server));
Craig Tiller60fd3612015-03-05 16:24:22 -0800787
Craig Tillera82950e2015-09-22 12:33:20 -0700788 GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
Craig Tiller60fd3612015-03-05 16:24:22 -0800789
Craig Tillera82950e2015-09-22 12:33:20 -0700790 memset(server, 0, sizeof(grpc_server));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800791
Craig Tillera82950e2015-09-22 12:33:20 -0700792 gpr_mu_init(&server->mu_global);
793 gpr_mu_init(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800794
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800795 /* decremented by grpc_server_destroy */
Craig Tillera82950e2015-09-22 12:33:20 -0700796 gpr_ref_init(&server->internal_refcount, 1);
797 server->root_channel_data.next = server->root_channel_data.prev =
798 &server->root_channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800799
Craig Tiller6a006ce2015-07-13 16:25:40 -0700800 /* TODO(ctiller): expose a channel_arg for this */
801 server->max_requested_calls = 32768;
Craig Tillera82950e2015-09-22 12:33:20 -0700802 server->request_freelist =
803 gpr_stack_lockfree_create(server->max_requested_calls);
804 for (i = 0; i < (size_t)server->max_requested_calls; i++) {
805 gpr_stack_lockfree_push(server->request_freelist, (int)i);
806 }
807 request_matcher_init(&server->unregistered_request_matcher,
808 server->max_requested_calls);
809 server->requested_calls = gpr_malloc(server->max_requested_calls *
810 sizeof(*server->requested_calls));
Craig Tiller729b35a2015-07-13 12:36:47 -0700811
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800812 /* Server filter stack is:
813
814 server_surface_filter - for making surface API calls
815 grpc_server_census_filter (optional) - for stats collection and tracing
816 {passed in filter stack}
817 grpc_connected_channel_filter - for interfacing with transports */
Craig Tiller32ca48c2015-09-10 11:47:15 -0700818 server->channel_filter_count = filter_count + 1u + (census_enabled ? 1u : 0u);
Craig Tillera82950e2015-09-22 12:33:20 -0700819 server->channel_filters =
820 gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800821 server->channel_filters[0] = &server_surface_filter;
Craig Tillera82950e2015-09-22 12:33:20 -0700822 if (census_enabled) {
823 server->channel_filters[1] = &grpc_server_census_filter;
824 }
825 for (i = 0; i < filter_count; i++) {
826 server->channel_filters[i + 1u + (census_enabled ? 1u : 0u)] = filters[i];
827 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800828
Craig Tillera82950e2015-09-22 12:33:20 -0700829 server->channel_args = grpc_channel_args_copy(args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800830
831 return server;
832}
833
Craig Tillera82950e2015-09-22 12:33:20 -0700834static int streq(const char *a, const char *b) {
835 if (a == NULL && b == NULL) return 1;
836 if (a == NULL) return 0;
837 if (b == NULL) return 0;
838 return 0 == strcmp(a, b);
Craig Tiller24be0f72015-02-10 14:04:22 -0800839}
840
Craig Tillera82950e2015-09-22 12:33:20 -0700841void *grpc_server_register_method(grpc_server *server, const char *method,
842 const char *host) {
Craig Tiller24be0f72015-02-10 14:04:22 -0800843 registered_method *m;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700844 GRPC_API_TRACE("grpc_server_register_method(server=%p, method=%s, host=%s)",
845 3, (server, method, host));
Craig Tillera82950e2015-09-22 12:33:20 -0700846 if (!method) {
847 gpr_log(GPR_ERROR,
848 "grpc_server_register_method method string cannot be NULL");
849 return NULL;
850 }
851 for (m = server->registered_methods; m; m = m->next) {
852 if (streq(m->method, method) && streq(m->host, host)) {
853 gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
854 host ? host : "*");
Craig Tiller24be0f72015-02-10 14:04:22 -0800855 return NULL;
856 }
Craig Tillera82950e2015-09-22 12:33:20 -0700857 }
858 m = gpr_malloc(sizeof(registered_method));
859 memset(m, 0, sizeof(*m));
860 request_matcher_init(&m->request_matcher, server->max_requested_calls);
861 m->method = gpr_strdup(method);
862 m->host = gpr_strdup(host);
Craig Tiller24be0f72015-02-10 14:04:22 -0800863 m->next = server->registered_methods;
864 server->registered_methods = m;
865 return m;
866}
867
Craig Tillera82950e2015-09-22 12:33:20 -0700868void grpc_server_start(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800869 listener *l;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800870 size_t i;
Craig Tillerf5768a62015-09-22 10:54:34 -0700871 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800872
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700873 GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
874
Craig Tillera82950e2015-09-22 12:33:20 -0700875 server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
876 for (i = 0; i < server->cq_count; i++) {
877 server->pollsets[i] = grpc_cq_pollset(server->cqs[i]);
878 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800879
Craig Tillera82950e2015-09-22 12:33:20 -0700880 for (l = server->listeners; l; l = l->next) {
881 l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count);
882 }
Craig Tillerdfff1b82015-09-21 14:39:57 -0700883
Craig Tillera82950e2015-09-22 12:33:20 -0700884 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800885}
886
Craig Tillera82950e2015-09-22 12:33:20 -0700887void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
888 grpc_transport *transport,
889 grpc_channel_filter const **extra_filters,
Craig Tillerb2b42612015-11-20 12:02:17 -0800890 size_t num_extra_filters,
Craig Tillera82950e2015-09-22 12:33:20 -0700891 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800892 size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700893 grpc_channel_filter const **filters =
894 gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800895 size_t i;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800896 size_t num_registered_methods;
897 size_t alloc;
898 registered_method *rm;
899 channel_registered_method *crm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800900 grpc_channel *channel;
901 channel_data *chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800902 grpc_mdstr *host;
903 grpc_mdstr *method;
904 gpr_uint32 hash;
Craig Tillerf96dfc32015-09-10 14:43:18 -0700905 size_t slots;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800906 gpr_uint32 probes;
907 gpr_uint32 max_probes = 0;
Craig Tillere039f032015-06-25 12:54:23 -0700908 grpc_transport_op op;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800909
Craig Tillera82950e2015-09-22 12:33:20 -0700910 for (i = 0; i < s->channel_filter_count; i++) {
911 filters[i] = s->channel_filters[i];
912 }
913 for (; i < s->channel_filter_count + num_extra_filters; i++) {
914 filters[i] = extra_filters[i - s->channel_filter_count];
915 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800916 filters[i] = &grpc_connected_channel_filter;
917
Craig Tillera82950e2015-09-22 12:33:20 -0700918 for (i = 0; i < s->cq_count; i++) {
919 memset(&op, 0, sizeof(op));
920 op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
921 grpc_transport_perform_op(exec_ctx, transport, &op);
922 }
ctillerd79b4862014-12-17 16:36:59 -0800923
Craig Tillera82950e2015-09-22 12:33:20 -0700924 channel = grpc_channel_create_from_filters(exec_ctx, NULL, filters,
Craig Tillerb2b42612015-11-20 12:02:17 -0800925 num_filters, args, 0);
Craig Tillera82950e2015-09-22 12:33:20 -0700926 chand = (channel_data *)grpc_channel_stack_element(
Craig Tiller71a0f9d2015-09-28 17:22:01 -0700927 grpc_channel_get_channel_stack(channel), 0)->channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800928 chand->server = s;
Craig Tillera82950e2015-09-22 12:33:20 -0700929 server_ref(s);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800930 chand->channel = channel;
931
Craig Tiller04cc8be2015-02-10 16:11:22 -0800932 num_registered_methods = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700933 for (rm = s->registered_methods; rm; rm = rm->next) {
934 num_registered_methods++;
935 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800936 /* build a lookup table phrased in terms of mdstr's in this channels context
937 to quickly find registered methods */
Craig Tillera82950e2015-09-22 12:33:20 -0700938 if (num_registered_methods > 0) {
939 slots = 2 * num_registered_methods;
940 alloc = sizeof(channel_registered_method) * slots;
941 chand->registered_methods = gpr_malloc(alloc);
942 memset(chand->registered_methods, 0, alloc);
943 for (rm = s->registered_methods; rm; rm = rm->next) {
Craig Tillerb2b42612015-11-20 12:02:17 -0800944 host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL;
945 method = grpc_mdstr_from_string(rm->method);
Craig Tillera82950e2015-09-22 12:33:20 -0700946 hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
947 for (probes = 0; chand->registered_methods[(hash + probes) % slots]
Craig Tiller71a0f9d2015-09-28 17:22:01 -0700948 .server_registered_method != NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700949 probes++)
950 ;
951 if (probes > max_probes) max_probes = probes;
952 crm = &chand->registered_methods[(hash + probes) % slots];
953 crm->server_registered_method = rm;
954 crm->host = host;
955 crm->method = method;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800956 }
Craig Tillera82950e2015-09-22 12:33:20 -0700957 GPR_ASSERT(slots <= GPR_UINT32_MAX);
958 chand->registered_method_slots = (gpr_uint32)slots;
959 chand->registered_method_max_probes = max_probes;
960 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800961
Craig Tillera82950e2015-09-22 12:33:20 -0700962 grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
963 transport);
Craig Tiller7bd5ab12015-02-17 22:29:04 -0800964
Craig Tillera82950e2015-09-22 12:33:20 -0700965 gpr_mu_lock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800966 chand->next = &s->root_channel_data;
967 chand->prev = chand->next->prev;
968 chand->next->prev = chand->prev->next = chand;
Craig Tillera82950e2015-09-22 12:33:20 -0700969 gpr_mu_unlock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800970
Craig Tiller565b18b2015-09-23 10:09:42 -0700971 gpr_free((void *)filters);
Craig Tiller4b804102015-06-26 16:16:12 -0700972
Craig Tillera82950e2015-09-22 12:33:20 -0700973 GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity");
974 memset(&op, 0, sizeof(op));
Craig Tiller4b804102015-06-26 16:16:12 -0700975 op.set_accept_stream = accept_stream;
976 op.set_accept_stream_user_data = chand;
977 op.on_connectivity_state_change = &chand->channel_connectivity_changed;
978 op.connectivity_state = &chand->connectivity_state;
Craig Tillera82950e2015-09-22 12:33:20 -0700979 op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0;
980 grpc_transport_perform_op(exec_ctx, transport, &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800981}
982
Craig Tillera82950e2015-09-22 12:33:20 -0700983void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg,
984 grpc_cq_completion *storage) {
985 (void)done_arg;
986 gpr_free(storage);
murgatroid9900a3dab2015-08-19 11:15:38 -0700987}
988
Craig Tillera82950e2015-09-22 12:33:20 -0700989static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s,
990 int success) {
Craig Tillerdfff1b82015-09-21 14:39:57 -0700991 grpc_server *server = s;
Craig Tillera82950e2015-09-22 12:33:20 -0700992 gpr_mu_lock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700993 server->listeners_destroyed++;
Craig Tillera82950e2015-09-22 12:33:20 -0700994 maybe_finish_shutdown(exec_ctx, server);
995 gpr_mu_unlock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700996}
997
Craig Tillera82950e2015-09-22 12:33:20 -0700998void grpc_server_shutdown_and_notify(grpc_server *server,
999 grpc_completion_queue *cq, void *tag) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001000 listener *l;
Craig Tillerbce999f2015-05-27 09:55:51 -07001001 shutdown_tag *sdt;
Craig Tillerff3ae682015-06-29 17:44:04 -07001002 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001003 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001004
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001005 GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3,
1006 (server, cq, tag));
1007
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001008 /* lock, and gather up some stuff to do */
Craig Tillera82950e2015-09-22 12:33:20 -07001009 gpr_mu_lock(&server->mu_global);
Craig Tiller4bf29282015-12-14 11:25:48 -08001010 grpc_cq_begin_op(cq, tag);
Craig Tillera82950e2015-09-22 12:33:20 -07001011 if (server->shutdown_published) {
1012 grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL,
1013 gpr_malloc(sizeof(grpc_cq_completion)));
1014 gpr_mu_unlock(&server->mu_global);
1015 goto done;
1016 }
1017 server->shutdown_tags =
1018 gpr_realloc(server->shutdown_tags,
1019 sizeof(shutdown_tag) * (server->num_shutdown_tags + 1));
Craig Tillerbce999f2015-05-27 09:55:51 -07001020 sdt = &server->shutdown_tags[server->num_shutdown_tags++];
1021 sdt->tag = tag;
1022 sdt->cq = cq;
Craig Tillera82950e2015-09-22 12:33:20 -07001023 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1024 gpr_mu_unlock(&server->mu_global);
1025 goto done;
1026 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001027
Craig Tillera82950e2015-09-22 12:33:20 -07001028 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
Craig Tillerab54f792015-07-08 08:34:20 -07001029
Craig Tillera82950e2015-09-22 12:33:20 -07001030 channel_broadcaster_init(server, &broadcaster);
nnoble0c475f02014-12-05 15:37:39 -08001031
Craig Tillerfc193e12015-09-24 15:29:03 -07001032 gpr_atm_rel_store(&server->shutdown_flag, 1);
1033
Craig Tillerbd217572015-02-11 18:10:56 -08001034 /* collect all unregistered then registered calls */
Craig Tillera82950e2015-09-22 12:33:20 -07001035 gpr_mu_lock(&server->mu_call);
1036 kill_pending_work_locked(&exec_ctx, server);
1037 gpr_mu_unlock(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001038
Craig Tillera82950e2015-09-22 12:33:20 -07001039 maybe_finish_shutdown(&exec_ctx, server);
1040 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001041
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001042 /* Shutdown listeners */
Craig Tillera82950e2015-09-22 12:33:20 -07001043 for (l = server->listeners; l; l = l->next) {
1044 grpc_closure_init(&l->destroy_done, listener_destroy_done, server);
1045 l->destroy(&exec_ctx, server, l->arg, &l->destroy_done);
1046 }
Craig Tillerff3ae682015-06-29 17:44:04 -07001047
Craig Tillera82950e2015-09-22 12:33:20 -07001048 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001049
Craig Tillerdfff1b82015-09-21 14:39:57 -07001050done:
Craig Tillera82950e2015-09-22 12:33:20 -07001051 grpc_exec_ctx_finish(&exec_ctx);
Craig Tilleraec96aa2015-04-07 14:32:15 -07001052}
1053
Craig Tillera82950e2015-09-22 12:33:20 -07001054void grpc_server_cancel_all_calls(grpc_server *server) {
Craig Tiller092d8d12015-07-04 22:35:00 -07001055 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001056 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillerafa2d632015-05-26 16:39:13 -07001057
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001058 GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server));
1059
Craig Tillera82950e2015-09-22 12:33:20 -07001060 gpr_mu_lock(&server->mu_global);
1061 channel_broadcaster_init(server, &broadcaster);
1062 gpr_mu_unlock(&server->mu_global);
Craig Tillerafa2d632015-05-26 16:39:13 -07001063
Craig Tillera82950e2015-09-22 12:33:20 -07001064 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1);
1065 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerafa2d632015-05-26 16:39:13 -07001066}
1067
Craig Tillera82950e2015-09-22 12:33:20 -07001068void grpc_server_destroy(grpc_server *server) {
Craig Tilleraec96aa2015-04-07 14:32:15 -07001069 listener *l;
Craig Tillerf5768a62015-09-22 10:54:34 -07001070 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller872af022015-04-24 15:57:52 -07001071
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001072 GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server));
1073
Craig Tillera82950e2015-09-22 12:33:20 -07001074 gpr_mu_lock(&server->mu_global);
1075 GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners);
1076 GPR_ASSERT(server->listeners_destroyed == num_listeners(server));
Craig Tilleraec96aa2015-04-07 14:32:15 -07001077
Craig Tillera82950e2015-09-22 12:33:20 -07001078 while (server->listeners) {
1079 l = server->listeners;
1080 server->listeners = l->next;
1081 gpr_free(l);
1082 }
Craig Tilleraec96aa2015-04-07 14:32:15 -07001083
Craig Tillera82950e2015-09-22 12:33:20 -07001084 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001085
Craig Tillera82950e2015-09-22 12:33:20 -07001086 server_unref(&exec_ctx, server);
1087 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001088}
1089
Craig Tillera82950e2015-09-22 12:33:20 -07001090void grpc_server_add_listener(
1091 grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1092 void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1093 grpc_pollset **pollsets, size_t pollset_count),
1094 void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1095 grpc_closure *on_done)) {
1096 listener *l = gpr_malloc(sizeof(listener));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001097 l->arg = arg;
1098 l->start = start;
1099 l->destroy = destroy;
1100 l->next = server->listeners;
1101 server->listeners = l;
1102}
1103
Craig Tillera82950e2015-09-22 12:33:20 -07001104static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1105 grpc_server *server,
1106 requested_call *rc) {
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001107 call_data *calld = NULL;
Craig Tillerb9d35962015-09-11 13:31:16 -07001108 request_matcher *rm = NULL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001109 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -07001110 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1111 fail_call(exec_ctx, server, rc);
1112 return GRPC_CALL_OK;
1113 }
1114 request_id = gpr_stack_lockfree_pop(server->request_freelist);
1115 if (request_id == -1) {
1116 /* out of request ids: just fail this one */
1117 fail_call(exec_ctx, server, rc);
1118 return GRPC_CALL_OK;
1119 }
1120 switch (rc->type) {
Craig Tiller04cc8be2015-02-10 16:11:22 -08001121 case BATCH_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001122 rm = &server->unregistered_request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001123 break;
1124 case REGISTERED_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001125 rm = &rc->data.registered.registered_method->request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001126 break;
Craig Tillera82950e2015-09-22 12:33:20 -07001127 }
Craig Tiller45724b32015-09-22 10:42:19 -07001128 server->requested_calls[request_id] = *rc;
Craig Tillera82950e2015-09-22 12:33:20 -07001129 gpr_free(rc);
Craig Tillerb9d35962015-09-11 13:31:16 -07001130 if (gpr_stack_lockfree_push(rm->requests, request_id)) {
Craig Tillera82950e2015-09-22 12:33:20 -07001131 /* this was the first queued request: we need to lock and start
1132 matching calls */
1133 gpr_mu_lock(&server->mu_call);
Craig Tillerb9d35962015-09-11 13:31:16 -07001134 while ((calld = rm->pending_head) != NULL) {
1135 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -07001136 if (request_id == -1) break;
Craig Tillerb9d35962015-09-11 13:31:16 -07001137 rm->pending_head = calld->pending_next;
Craig Tillera82950e2015-09-22 12:33:20 -07001138 gpr_mu_unlock(&server->mu_call);
1139 gpr_mu_lock(&calld->mu_state);
1140 if (calld->state == ZOMBIED) {
1141 gpr_mu_unlock(&calld->mu_state);
1142 grpc_closure_init(
1143 &calld->kill_zombie_closure, kill_zombie,
1144 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
1145 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
1146 } else {
1147 GPR_ASSERT(calld->state == PENDING);
1148 calld->state = ACTIVATED;
1149 gpr_mu_unlock(&calld->mu_state);
1150 begin_call(exec_ctx, server, calld,
1151 &server->requested_calls[request_id]);
1152 }
1153 gpr_mu_lock(&server->mu_call);
Craig Tiller45724b32015-09-22 10:42:19 -07001154 }
Craig Tillera82950e2015-09-22 12:33:20 -07001155 gpr_mu_unlock(&server->mu_call);
1156 }
Craig Tiller6a006ce2015-07-13 16:25:40 -07001157 return GRPC_CALL_OK;
Craig Tillercce17ac2015-01-20 09:29:28 -08001158}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001159
Craig Tillera82950e2015-09-22 12:33:20 -07001160grpc_call_error grpc_server_request_call(
1161 grpc_server *server, grpc_call **call, grpc_call_details *details,
1162 grpc_metadata_array *initial_metadata,
1163 grpc_completion_queue *cq_bound_to_call,
1164 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001165 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001166 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001167 requested_call *rc = gpr_malloc(sizeof(*rc));
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001168 GRPC_API_TRACE(
1169 "grpc_server_request_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001170 "server=%p, call=%p, details=%p, initial_metadata=%p, "
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001171 "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001172 7, (server, call, details, initial_metadata, cq_bound_to_call,
1173 cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001174 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1175 gpr_free(rc);
1176 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1177 goto done;
1178 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001179 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller9928d392015-08-18 09:40:24 -07001180 details->reserved = NULL;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001181 rc->type = BATCH_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001182 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001183 rc->tag = tag;
1184 rc->cq_bound_to_call = cq_bound_to_call;
1185 rc->cq_for_notification = cq_for_notification;
1186 rc->call = call;
1187 rc->data.batch.details = details;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001188 rc->initial_metadata = initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -07001189 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001190done:
Craig Tillera82950e2015-09-22 12:33:20 -07001191 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001192 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001193}
1194
Craig Tillera82950e2015-09-22 12:33:20 -07001195grpc_call_error grpc_server_request_registered_call(
Craig Tillerb9d35962015-09-11 13:31:16 -07001196 grpc_server *server, void *rmp, grpc_call **call, gpr_timespec *deadline,
Craig Tillera82950e2015-09-22 12:33:20 -07001197 grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload,
1198 grpc_completion_queue *cq_bound_to_call,
1199 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001200 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001201 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001202 requested_call *rc = gpr_malloc(sizeof(*rc));
Craig Tillerb9d35962015-09-11 13:31:16 -07001203 registered_method *rm = rmp;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001204 GRPC_API_TRACE(
1205 "grpc_server_request_registered_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001206 "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, "
1207 "optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
1208 "tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001209 9, (server, rmp, call, deadline, initial_metadata, optional_payload,
1210 cq_bound_to_call, cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001211 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1212 gpr_free(rc);
1213 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1214 goto done;
1215 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001216 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001217 rc->type = REGISTERED_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;
Craig Tillerb9d35962015-09-11 13:31:16 -07001223 rc->data.registered.registered_method = rm;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001224 rc->data.registered.deadline = deadline;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001225 rc->initial_metadata = initial_metadata;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001226 rc->data.registered.optional_payload = optional_payload;
Craig Tillera82950e2015-09-22 12:33:20 -07001227 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001228done:
Craig Tillera82950e2015-09-22 12:33:20 -07001229 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001230 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001231}
1232
Craig Tillera82950e2015-09-22 12:33:20 -07001233static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001234 void *user_data, int success);
Craig Tiller24be0f72015-02-10 14:04:22 -08001235
Craig Tillera82950e2015-09-22 12:33:20 -07001236static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
Craig Tiller166e2502015-02-03 20:14:41 -08001237 gpr_slice slice = value->slice;
Craig Tillera82950e2015-09-22 12:33:20 -07001238 size_t len = GPR_SLICE_LENGTH(slice);
Craig Tiller166e2502015-02-03 20:14:41 -08001239
Craig Tillera82950e2015-09-22 12:33:20 -07001240 if (len + 1 > *capacity) {
1241 *capacity = GPR_MAX(len + 1, *capacity * 2);
1242 *dest = gpr_realloc(*dest, *capacity);
1243 }
1244 memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
Craig Tiller166e2502015-02-03 20:14:41 -08001245}
1246
Craig Tillera82950e2015-09-22 12:33:20 -07001247static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1248 call_data *calld, requested_call *rc) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001249 grpc_op ops[1];
1250 grpc_op *op = ops;
1251
1252 memset(ops, 0, sizeof(ops));
Craig Tiller24be0f72015-02-10 14:04:22 -08001253
1254 /* called once initial metadata has been read by the call, but BEFORE
1255 the ioreq to fetch it out of the call has been executed.
1256 This means metadata related fields can be relied on in calld, but to
1257 fill in the metadata array passed by the client, we need to perform
1258 an ioreq op, that should complete immediately. */
1259
Craig Tillera82950e2015-09-22 12:33:20 -07001260 grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001261 grpc_closure_init(&rc->publish, publish_registered_or_batch, rc);
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001262 *rc->call = calld->call;
1263 calld->cq_new = rc->cq_for_notification;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001264 GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
Craig Tillera82950e2015-09-22 12:33:20 -07001265 switch (rc->type) {
Craig Tiller24be0f72015-02-10 14:04:22 -08001266 case BATCH_CALL:
Craig Tillera82950e2015-09-22 12:33:20 -07001267 GPR_ASSERT(calld->host != NULL);
1268 GPR_ASSERT(calld->path != NULL);
1269 cpstr(&rc->data.batch.details->host,
1270 &rc->data.batch.details->host_capacity, calld->host);
1271 cpstr(&rc->data.batch.details->method,
1272 &rc->data.batch.details->method_capacity, calld->path);
Masood Malekghassemibf177c82015-04-27 12:14:38 -07001273 rc->data.batch.details->deadline = calld->deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -08001274 break;
1275 case REGISTERED_CALL:
1276 *rc->data.registered.deadline = calld->deadline;
Craig Tillera82950e2015-09-22 12:33:20 -07001277 if (rc->data.registered.optional_payload) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001278 op->op = GRPC_OP_RECV_MESSAGE;
1279 op->data.recv_message = rc->data.registered.optional_payload;
1280 op++;
Craig Tillera82950e2015-09-22 12:33:20 -07001281 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001282 break;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001283 default:
1284 GPR_UNREACHABLE_CODE(return );
Craig Tillera82950e2015-09-22 12:33:20 -07001285 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001286
Craig Tillera82950e2015-09-22 12:33:20 -07001287 GRPC_CALL_INTERNAL_REF(calld->call, "server");
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001288 grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops,
1289 (size_t)(op - ops), &rc->publish);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001290}
1291
Craig Tillera82950e2015-09-22 12:33:20 -07001292static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
1293 grpc_cq_completion *c) {
Craig Tiller6a006ce2015-07-13 16:25:40 -07001294 requested_call *rc = req;
1295 grpc_server *server = rc->server;
1296
Craig Tillera82950e2015-09-22 12:33:20 -07001297 if (rc >= server->requested_calls &&
1298 rc < server->requested_calls + server->max_requested_calls) {
1299 GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
1300 gpr_stack_lockfree_push(server->request_freelist,
1301 (int)(rc - server->requested_calls));
1302 } else {
1303 gpr_free(req);
1304 }
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001305
Craig Tillera82950e2015-09-22 12:33:20 -07001306 server_unref(exec_ctx, server);
Craig Tiller24be0f72015-02-10 14:04:22 -08001307}
1308
Craig Tillera82950e2015-09-22 12:33:20 -07001309static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1310 requested_call *rc) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001311 *rc->call = NULL;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001312 rc->initial_metadata->count = 0;
1313
Craig Tillera82950e2015-09-22 12:33:20 -07001314 server_ref(server);
1315 grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
1316 done_request_event, rc, &rc->completion);
Craig Tiller24be0f72015-02-10 14:04:22 -08001317}
1318
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001319static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc,
1320 int success) {
1321 requested_call *rc = prc;
1322 grpc_call *call = *rc->call;
Craig Tillera82950e2015-09-22 12:33:20 -07001323 grpc_call_element *elem =
1324 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
Craig Tiller20bc56d2015-02-12 09:02:56 -08001325 call_data *calld = elem->call_data;
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001326 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001327 server_ref(chand->server);
1328 grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event,
1329 rc, &rc->completion);
1330 GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server");
Craig Tiller24be0f72015-02-10 14:04:22 -08001331}
1332
Craig Tillera82950e2015-09-22 12:33:20 -07001333const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001334 return server->channel_args;
Craig Tiller190d3602015-02-18 09:23:38 -08001335}
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001336
Craig Tillera82950e2015-09-22 12:33:20 -07001337int grpc_server_has_open_connections(grpc_server *server) {
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001338 int r;
Craig Tillera82950e2015-09-22 12:33:20 -07001339 gpr_mu_lock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001340 r = server->root_channel_data.next != &server->root_channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001341 gpr_mu_unlock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001342 return r;
1343}