blob: 28d0e8938d340b5f0a8039107b01043110249a7a [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"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080051#include "src/core/surface/call.h"
52#include "src/core/surface/channel.h"
53#include "src/core/surface/completion_queue.h"
Craig Tiller60fd3612015-03-05 16:24:22 -080054#include "src/core/surface/init.h"
Craig Tillercce17ac2015-01-20 09:29:28 -080055#include "src/core/transport/metadata.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080056
Craig Tillera82950e2015-09-22 12:33:20 -070057typedef struct listener {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080058 void *arg;
Craig Tillera82950e2015-09-22 12:33:20 -070059 void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
60 grpc_pollset **pollsets, size_t pollset_count);
61 void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
62 grpc_closure *closure);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080063 struct listener *next;
Craig Tillerdfff1b82015-09-21 14:39:57 -070064 grpc_closure destroy_done;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080065} listener;
66
67typedef struct call_data call_data;
68typedef struct channel_data channel_data;
Craig Tiller24be0f72015-02-10 14:04:22 -080069typedef struct registered_method registered_method;
70
Craig Tillera82950e2015-09-22 12:33:20 -070071typedef struct {
Craig Tiller24be0f72015-02-10 14:04:22 -080072 call_data *next;
73 call_data *prev;
74} call_link;
75
Craig Tillera82950e2015-09-22 12:33:20 -070076typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type;
Craig Tiller24be0f72015-02-10 14:04:22 -080077
Craig Tillera82950e2015-09-22 12:33:20 -070078typedef struct requested_call {
Craig Tiller24be0f72015-02-10 14:04:22 -080079 requested_call_type type;
80 void *tag;
Craig Tiller6a006ce2015-07-13 16:25:40 -070081 grpc_server *server;
Craig Tillerf9e6adf2015-05-06 11:45:59 -070082 grpc_completion_queue *cq_bound_to_call;
83 grpc_completion_queue *cq_for_notification;
84 grpc_call **call;
Craig Tiller97fc6a32015-07-08 15:31:35 -070085 grpc_cq_completion completion;
Craig Tillera82950e2015-09-22 12:33:20 -070086 union {
87 struct {
Craig Tiller24be0f72015-02-10 14:04:22 -080088 grpc_call_details *details;
89 grpc_metadata_array *initial_metadata;
90 } batch;
Craig Tillera82950e2015-09-22 12:33:20 -070091 struct {
Craig Tiller24be0f72015-02-10 14:04:22 -080092 registered_method *registered_method;
93 gpr_timespec *deadline;
94 grpc_metadata_array *initial_metadata;
95 grpc_byte_buffer **optional_payload;
96 } registered;
97 } data;
98} requested_call;
99
Craig Tillera82950e2015-09-22 12:33:20 -0700100typedef struct channel_registered_method {
Craig Tiller24be0f72015-02-10 14:04:22 -0800101 registered_method *server_registered_method;
102 grpc_mdstr *method;
103 grpc_mdstr *host;
104} channel_registered_method;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800105
Craig Tillera82950e2015-09-22 12:33:20 -0700106struct channel_data {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800107 grpc_server *server;
Craig Tillere039f032015-06-25 12:54:23 -0700108 grpc_connectivity_state connectivity_state;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800109 grpc_channel *channel;
Craig Tillercce17ac2015-01-20 09:29:28 -0800110 grpc_mdstr *path_key;
111 grpc_mdstr *authority_key;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800112 /* 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;
152 int got_initial_metadata;
Craig Tillercce17ac2015-01-20 09:29:28 -0800153
Craig Tiller20bc56d2015-02-12 09:02:56 -0800154 grpc_completion_queue *cq_new;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800155
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700156 grpc_stream_op_buffer *recv_ops;
157 grpc_stream_state *recv_state;
Craig Tiller33825112015-09-18 07:44:19 -0700158 grpc_closure *on_done_recv;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700159
Craig Tiller33825112015-09-18 07:44:19 -0700160 grpc_closure server_on_recv;
161 grpc_closure kill_zombie_closure;
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 Tiller82f9bd82015-09-23 09:31:51 -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 Tillera82950e2015-09-22 12:33:20 -0700306static void request_matcher_init(request_matcher *request_matcher,
307 size_t entries) {
308 memset(request_matcher, 0, sizeof(*request_matcher));
309 request_matcher->requests = gpr_stack_lockfree_create(entries);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800310}
311
Craig Tillera82950e2015-09-22 12:33:20 -0700312static void request_matcher_destroy(request_matcher *request_matcher) {
313 GPR_ASSERT(gpr_stack_lockfree_pop(request_matcher->requests) == -1);
314 gpr_stack_lockfree_destroy(request_matcher->requests);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800315}
316
Craig Tillera82950e2015-09-22 12:33:20 -0700317static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, int success) {
318 grpc_call_destroy(grpc_call_from_top_element(elem));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800319}
320
Craig Tillera82950e2015-09-22 12:33:20 -0700321static void request_matcher_zombify_all_pending_calls(
322 grpc_exec_ctx *exec_ctx, request_matcher *request_matcher) {
323 while (request_matcher->pending_head) {
324 call_data *calld = request_matcher->pending_head;
325 request_matcher->pending_head = calld->pending_next;
326 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));
332 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
333 }
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 Tiller82f9bd82015-09-23 09:31:51 -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,
396 int 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 gpr_log(GPR_DEBUG, "finish_destroy_channel: %p", chand->channel);
400 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server");
401 server_unref(exec_ctx, server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800402}
403
Craig Tillera82950e2015-09-22 12:33:20 -0700404static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) {
405 if (is_channel_orphaned(chand)) return;
406 GPR_ASSERT(chand->server != NULL);
407 orphan_channel(chand);
408 server_ref(chand->server);
409 maybe_finish_shutdown(exec_ctx, chand->server);
David Garcia Quintas284488b2015-05-28 16:27:39 -0700410 chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
411 chand->finish_destroy_channel_closure.cb_arg = chand;
Craig Tillera82950e2015-09-22 12:33:20 -0700412 grpc_exec_ctx_enqueue(exec_ctx, &chand->finish_destroy_channel_closure, 1);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800413}
414
Craig Tillera82950e2015-09-22 12:33:20 -0700415static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server,
416 grpc_call_element *elem,
417 request_matcher *request_matcher) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800418 call_data *calld = elem->call_data;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700419 int request_id;
420
Craig Tillera82950e2015-09-22 12:33:20 -0700421 if (gpr_atm_acq_load(&server->shutdown_flag)) {
422 gpr_mu_lock(&calld->mu_state);
423 calld->state = ZOMBIED;
424 gpr_mu_unlock(&calld->mu_state);
425 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
426 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
427 return;
428 }
Craig Tiller45724b32015-09-22 10:42:19 -0700429
Craig Tillera82950e2015-09-22 12:33:20 -0700430 request_id = gpr_stack_lockfree_pop(request_matcher->requests);
431 if (request_id == -1) {
432 gpr_mu_lock(&server->mu_call);
433 gpr_mu_lock(&calld->mu_state);
434 calld->state = PENDING;
435 gpr_mu_unlock(&calld->mu_state);
436 if (request_matcher->pending_head == NULL) {
437 request_matcher->pending_tail = request_matcher->pending_head = calld;
438 } else {
439 request_matcher->pending_tail->pending_next = calld;
440 request_matcher->pending_tail = calld;
Craig Tiller45724b32015-09-22 10:42:19 -0700441 }
Craig Tillera82950e2015-09-22 12:33:20 -0700442 calld->pending_next = NULL;
443 gpr_mu_unlock(&server->mu_call);
444 } else {
445 gpr_mu_lock(&calld->mu_state);
446 calld->state = ACTIVATED;
447 gpr_mu_unlock(&calld->mu_state);
448 begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
449 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800450}
451
Craig Tillera82950e2015-09-22 12:33:20 -0700452static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800453 channel_data *chand = elem->channel_data;
454 call_data *calld = elem->call_data;
455 grpc_server *server = chand->server;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800456 gpr_uint32 i;
457 gpr_uint32 hash;
458 channel_registered_method *rm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800459
Craig Tillera82950e2015-09-22 12:33:20 -0700460 if (chand->registered_methods && calld->path && calld->host) {
461 /* TODO(ctiller): unify these two searches */
462 /* check for an exact match with host */
463 hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
464 for (i = 0; i <= chand->registered_method_max_probes; i++) {
465 rm = &chand->registered_methods[(hash + i) %
466 chand->registered_method_slots];
467 if (!rm) break;
468 if (rm->host != calld->host) continue;
469 if (rm->method != calld->path) continue;
470 finish_start_new_rpc(exec_ctx, server, elem,
471 &rm->server_registered_method->request_matcher);
472 return;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800473 }
Craig Tillera82950e2015-09-22 12:33:20 -0700474 /* check for a wildcard method definition (no host set) */
475 hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
476 for (i = 0; i <= chand->registered_method_max_probes; i++) {
477 rm = &chand->registered_methods[(hash + i) %
478 chand->registered_method_slots];
479 if (!rm) break;
480 if (rm->host != NULL) continue;
481 if (rm->method != calld->path) continue;
482 finish_start_new_rpc(exec_ctx, server, elem,
483 &rm->server_registered_method->request_matcher);
484 return;
485 }
486 }
487 finish_start_new_rpc(exec_ctx, server, elem,
488 &server->unregistered_request_matcher);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800489}
490
Craig Tillera82950e2015-09-22 12:33:20 -0700491static int num_listeners(grpc_server *server) {
Craig Tilleree945e82015-05-26 16:15:34 -0700492 listener *l;
493 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700494 for (l = server->listeners; l; l = l->next) {
495 n++;
496 }
Craig Tilleree945e82015-05-26 16:15:34 -0700497 return n;
498}
499
Craig Tillera82950e2015-09-22 12:33:20 -0700500static void done_shutdown_event(grpc_exec_ctx *exec_ctx, void *server,
501 grpc_cq_completion *completion) {
502 server_unref(exec_ctx, server);
Craig Tiller97fc6a32015-07-08 15:31:35 -0700503}
504
Craig Tillera82950e2015-09-22 12:33:20 -0700505static int num_channels(grpc_server *server) {
Craig Tillerab54f792015-07-08 08:34:20 -0700506 channel_data *chand;
507 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700508 for (chand = server->root_channel_data.next;
509 chand != &server->root_channel_data; chand = chand->next) {
510 n++;
511 }
Craig Tillerab54f792015-07-08 08:34:20 -0700512 return n;
513}
514
Craig Tillera82950e2015-09-22 12:33:20 -0700515static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx,
516 grpc_server *server) {
Craig Tiller1191e212015-07-30 14:49:02 -0700517 registered_method *rm;
Craig Tillera82950e2015-09-22 12:33:20 -0700518 request_matcher_kill_requests(exec_ctx, server,
519 &server->unregistered_request_matcher);
520 request_matcher_zombify_all_pending_calls(
521 exec_ctx, &server->unregistered_request_matcher);
522 for (rm = server->registered_methods; rm; rm = rm->next) {
523 request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher);
524 request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
525 }
Craig Tillerdc627722015-05-26 15:27:02 -0700526}
527
Craig Tillera82950e2015-09-22 12:33:20 -0700528static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
529 grpc_server *server) {
Craig Tiller45724b32015-09-22 10:42:19 -0700530 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700531 if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) {
532 return;
533 }
Craig Tiller45724b32015-09-22 10:42:19 -0700534
Craig Tillera82950e2015-09-22 12:33:20 -0700535 kill_pending_work_locked(exec_ctx, server);
Craig Tiller45724b32015-09-22 10:42:19 -0700536
Craig Tillera82950e2015-09-22 12:33:20 -0700537 if (server->root_channel_data.next != &server->root_channel_data ||
538 server->listeners_destroyed < num_listeners(server)) {
539 if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
540 server->last_shutdown_message_time),
541 gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
542 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
543 gpr_log(GPR_DEBUG,
544 "Waiting for %d channels and %d/%d listeners to be destroyed"
545 " before shutting down server",
546 num_channels(server),
547 num_listeners(server) - server->listeners_destroyed,
548 num_listeners(server));
Craig Tiller45724b32015-09-22 10:42:19 -0700549 }
Craig Tillera82950e2015-09-22 12:33:20 -0700550 return;
551 }
Craig Tiller45724b32015-09-22 10:42:19 -0700552 server->shutdown_published = 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700553 for (i = 0; i < server->num_shutdown_tags; i++) {
554 server_ref(server);
555 grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq,
556 server->shutdown_tags[i].tag, 1, done_shutdown_event, server,
557 &server->shutdown_tags[i].completion);
558 }
Craig Tiller45724b32015-09-22 10:42:19 -0700559}
560
Craig Tillera82950e2015-09-22 12:33:20 -0700561static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
Craig Tiller6902ad22015-04-16 08:01:49 -0700562 grpc_call_element *elem = user_data;
Craig Tillercce17ac2015-01-20 09:29:28 -0800563 channel_data *chand = elem->channel_data;
564 call_data *calld = elem->call_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700565 if (md->key == chand->path_key) {
566 calld->path = GRPC_MDSTR_REF(md->value);
567 return NULL;
568 } else if (md->key == chand->authority_key) {
569 calld->host = GRPC_MDSTR_REF(md->value);
570 return NULL;
571 }
Craig Tiller6902ad22015-04-16 08:01:49 -0700572 return md;
573}
574
Craig Tillera82950e2015-09-22 12:33:20 -0700575static void server_on_recv(grpc_exec_ctx *exec_ctx, void *ptr, int success) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700576 grpc_call_element *elem = ptr;
Craig Tiller6902ad22015-04-16 08:01:49 -0700577 call_data *calld = elem->call_data;
Craig Tiller94329d02015-07-23 09:52:11 -0700578 gpr_timespec op_deadline;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700579
Craig Tillera82950e2015-09-22 12:33:20 -0700580 if (success && !calld->got_initial_metadata) {
581 size_t i;
582 size_t nops = calld->recv_ops->nops;
583 grpc_stream_op *ops = calld->recv_ops->ops;
584 for (i = 0; i < nops; i++) {
585 grpc_stream_op *op = &ops[i];
586 if (op->type != GRPC_OP_METADATA) continue;
587 grpc_metadata_batch_filter(&op->data.metadata, server_filter, elem);
588 op_deadline = op->data.metadata.deadline;
589 if (0 !=
590 gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
591 calld->deadline = op->data.metadata.deadline;
592 }
593 if (calld->host && calld->path) {
594 calld->got_initial_metadata = 1;
595 start_new_rpc(exec_ctx, elem);
596 }
597 break;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700598 }
Craig Tillera82950e2015-09-22 12:33:20 -0700599 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700600
Craig Tillera82950e2015-09-22 12:33:20 -0700601 switch (*calld->recv_state) {
Craig Tiller06aeea72015-04-23 10:54:45 -0700602 case GRPC_STREAM_OPEN:
603 break;
604 case GRPC_STREAM_SEND_CLOSED:
605 break;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700606 case GRPC_STREAM_RECV_CLOSED:
Craig Tillera82950e2015-09-22 12:33:20 -0700607 gpr_mu_lock(&calld->mu_state);
608 if (calld->state == NOT_STARTED) {
609 calld->state = ZOMBIED;
610 gpr_mu_unlock(&calld->mu_state);
611 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
612 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
613 } else {
614 gpr_mu_unlock(&calld->mu_state);
615 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800616 break;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700617 case GRPC_STREAM_CLOSED:
Craig Tillera82950e2015-09-22 12:33:20 -0700618 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 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800632 break;
Craig Tillera82950e2015-09-22 12:33:20 -0700633 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700634
Craig Tillera82950e2015-09-22 12:33:20 -0700635 calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, success);
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700636}
637
Craig Tillera82950e2015-09-22 12:33:20 -0700638static void server_mutate_op(grpc_call_element *elem,
639 grpc_transport_stream_op *op) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700640 call_data *calld = elem->call_data;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700641
Craig Tillera82950e2015-09-22 12:33:20 -0700642 if (op->recv_ops) {
643 /* substitute our callback for the higher callback */
644 calld->recv_ops = op->recv_ops;
645 calld->recv_state = op->recv_state;
646 calld->on_done_recv = op->on_done_recv;
647 op->on_done_recv = &calld->server_on_recv;
648 }
Craig Tiller50d9db52015-04-23 10:52:14 -0700649}
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700650
Craig Tillera82950e2015-09-22 12:33:20 -0700651static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
652 grpc_call_element *elem,
653 grpc_transport_stream_op *op) {
654 GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
655 server_mutate_op(elem, op);
656 grpc_call_next_op(exec_ctx, elem, op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800657}
658
Craig Tillera82950e2015-09-22 12:33:20 -0700659static void accept_stream(void *cd, grpc_transport *transport,
660 const void *transport_server_data) {
Craig Tillere039f032015-06-25 12:54:23 -0700661 channel_data *chand = cd;
662 /* create a call */
Craig Tillera82950e2015-09-22 12:33:20 -0700663 grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data, NULL,
664 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
Craig Tillere039f032015-06-25 12:54:23 -0700665}
666
Craig Tillera82950e2015-09-22 12:33:20 -0700667static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd,
668 int iomgr_status_ignored) {
Craig Tillere039f032015-06-25 12:54:23 -0700669 channel_data *chand = cd;
670 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700671 if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
672 grpc_transport_op op;
673 memset(&op, 0, sizeof(op));
674 op.on_connectivity_state_change = &chand->channel_connectivity_changed,
675 op.connectivity_state = &chand->connectivity_state;
676 grpc_channel_next_op(exec_ctx,
677 grpc_channel_stack_element(
678 grpc_channel_get_channel_stack(chand->channel), 0),
679 &op);
680 } else {
681 gpr_mu_lock(&server->mu_global);
682 destroy_channel(exec_ctx, chand);
683 gpr_mu_unlock(&server->mu_global);
684 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity");
685 }
Craig Tillere039f032015-06-25 12:54:23 -0700686}
687
Craig Tillera82950e2015-09-22 12:33:20 -0700688static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
689 const void *server_transport_data,
690 grpc_transport_stream_op *initial_op) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800691 call_data *calld = elem->call_data;
692 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700693 memset(calld, 0, sizeof(call_data));
694 calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
695 calld->call = grpc_call_from_top_element(elem);
696 gpr_mu_init(&calld->mu_state);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800697
Craig Tillera82950e2015-09-22 12:33:20 -0700698 grpc_closure_init(&calld->server_on_recv, server_on_recv, elem);
Craig Tiller1e6facb2015-06-11 22:47:11 -0700699
Craig Tillera82950e2015-09-22 12:33:20 -0700700 server_ref(chand->server);
Craig Tiller50d9db52015-04-23 10:52:14 -0700701
Craig Tillera82950e2015-09-22 12:33:20 -0700702 if (initial_op) server_mutate_op(elem, initial_op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800703}
704
Craig Tillera82950e2015-09-22 12:33:20 -0700705static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
706 grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800707 channel_data *chand = elem->channel_data;
Craig Tillerdb7db992015-01-29 11:19:01 -0800708 call_data *calld = elem->call_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800709
Craig Tillera82950e2015-09-22 12:33:20 -0700710 GPR_ASSERT(calld->state != PENDING);
Craig Tiller092d8d12015-07-04 22:35:00 -0700711
Craig Tillera82950e2015-09-22 12:33:20 -0700712 if (calld->host) {
713 GRPC_MDSTR_UNREF(calld->host);
714 }
715 if (calld->path) {
716 GRPC_MDSTR_UNREF(calld->path);
717 }
Craig Tiller4df31a62015-01-30 09:44:31 -0800718
Craig Tillera82950e2015-09-22 12:33:20 -0700719 gpr_mu_destroy(&calld->mu_state);
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700720
Craig Tillera82950e2015-09-22 12:33:20 -0700721 server_unref(exec_ctx, chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800722}
723
Craig Tillera82950e2015-09-22 12:33:20 -0700724static void init_channel_elem(grpc_exec_ctx *exec_ctx,
725 grpc_channel_element *elem, grpc_channel *master,
726 const grpc_channel_args *args,
727 grpc_mdctx *metadata_context, int is_first,
728 int is_last) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800729 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700730 GPR_ASSERT(is_first);
731 GPR_ASSERT(!is_last);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800732 chand->server = NULL;
733 chand->channel = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700734 chand->path_key = grpc_mdstr_from_string(metadata_context, ":path", 0);
735 chand->authority_key =
736 grpc_mdstr_from_string(metadata_context, ":authority", 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800737 chand->next = chand->prev = chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800738 chand->registered_methods = NULL;
Craig Tillere039f032015-06-25 12:54:23 -0700739 chand->connectivity_state = GRPC_CHANNEL_IDLE;
Craig Tillera82950e2015-09-22 12:33:20 -0700740 grpc_closure_init(&chand->channel_connectivity_changed,
741 channel_connectivity_changed, chand);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800742}
743
Craig Tillera82950e2015-09-22 12:33:20 -0700744static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
745 grpc_channel_element *elem) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800746 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800747 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700748 if (chand->registered_methods) {
749 for (i = 0; i < chand->registered_method_slots; i++) {
750 if (chand->registered_methods[i].method) {
751 GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
752 }
753 if (chand->registered_methods[i].host) {
754 GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
755 }
Craig Tillerec3257c2015-02-12 15:59:43 -0800756 }
Craig Tillera82950e2015-09-22 12:33:20 -0700757 gpr_free(chand->registered_methods);
758 }
759 if (chand->server) {
760 gpr_mu_lock(&chand->server->mu_global);
761 chand->next->prev = chand->prev;
762 chand->prev->next = chand->next;
763 chand->next = chand->prev = chand;
764 maybe_finish_shutdown(exec_ctx, chand->server);
765 gpr_mu_unlock(&chand->server->mu_global);
766 GRPC_MDSTR_UNREF(chand->path_key);
767 GRPC_MDSTR_UNREF(chand->authority_key);
768 server_unref(exec_ctx, chand->server);
769 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800770}
771
772static const grpc_channel_filter server_surface_filter = {
Craig Tillera82950e2015-09-22 12:33:20 -0700773 server_start_transport_stream_op,
774 grpc_channel_next_op,
775 sizeof(call_data),
776 init_call_elem,
777 destroy_call_elem,
778 sizeof(channel_data),
779 init_channel_elem,
780 destroy_channel_elem,
781 grpc_call_next_get_peer,
782 "server",
Craig Tiller9f28ac22015-01-27 17:01:29 -0800783};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800784
Craig Tillera82950e2015-09-22 12:33:20 -0700785void grpc_server_register_completion_queue(grpc_server *server,
786 grpc_completion_queue *cq,
787 void *reserved) {
Craig Tiller20bc56d2015-02-12 09:02:56 -0800788 size_t i, n;
Craig Tillera82950e2015-09-22 12:33:20 -0700789 GPR_ASSERT(!reserved);
790 for (i = 0; i < server->cq_count; i++) {
791 if (server->cqs[i] == cq) return;
792 }
793 GRPC_CQ_INTERNAL_REF(cq, "server");
794 grpc_cq_mark_server_cq(cq);
Craig Tiller20bc56d2015-02-12 09:02:56 -0800795 n = server->cq_count++;
Craig Tillera82950e2015-09-22 12:33:20 -0700796 server->cqs = gpr_realloc(server->cqs,
797 server->cq_count * sizeof(grpc_completion_queue *));
Craig Tiller20bc56d2015-02-12 09:02:56 -0800798 server->cqs[n] = cq;
799}
800
Craig Tillera82950e2015-09-22 12:33:20 -0700801grpc_server *grpc_server_create_from_filters(
802 const grpc_channel_filter **filters, size_t filter_count,
803 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800804 size_t i;
Alistair Veitch9d48ebf2015-06-01 10:01:03 -0700805 /* TODO(census): restore this once we finalize census filter etc.
806 int census_enabled = grpc_channel_args_is_census_enabled(args); */
807 int census_enabled = 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800808
Craig Tillera82950e2015-09-22 12:33:20 -0700809 grpc_server *server = gpr_malloc(sizeof(grpc_server));
Craig Tiller60fd3612015-03-05 16:24:22 -0800810
Craig Tillera82950e2015-09-22 12:33:20 -0700811 GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
Craig Tiller60fd3612015-03-05 16:24:22 -0800812
Craig Tillera82950e2015-09-22 12:33:20 -0700813 memset(server, 0, sizeof(grpc_server));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800814
Craig Tillera82950e2015-09-22 12:33:20 -0700815 gpr_mu_init(&server->mu_global);
816 gpr_mu_init(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800817
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800818 /* decremented by grpc_server_destroy */
Craig Tillera82950e2015-09-22 12:33:20 -0700819 gpr_ref_init(&server->internal_refcount, 1);
820 server->root_channel_data.next = server->root_channel_data.prev =
821 &server->root_channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800822
Craig Tiller6a006ce2015-07-13 16:25:40 -0700823 /* TODO(ctiller): expose a channel_arg for this */
824 server->max_requested_calls = 32768;
Craig Tillera82950e2015-09-22 12:33:20 -0700825 server->request_freelist =
826 gpr_stack_lockfree_create(server->max_requested_calls);
827 for (i = 0; i < (size_t)server->max_requested_calls; i++) {
828 gpr_stack_lockfree_push(server->request_freelist, (int)i);
829 }
830 request_matcher_init(&server->unregistered_request_matcher,
831 server->max_requested_calls);
832 server->requested_calls = gpr_malloc(server->max_requested_calls *
833 sizeof(*server->requested_calls));
Craig Tiller729b35a2015-07-13 12:36:47 -0700834
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800835 /* Server filter stack is:
836
837 server_surface_filter - for making surface API calls
838 grpc_server_census_filter (optional) - for stats collection and tracing
839 {passed in filter stack}
840 grpc_connected_channel_filter - for interfacing with transports */
Craig Tiller32ca48c2015-09-10 11:47:15 -0700841 server->channel_filter_count = filter_count + 1u + (census_enabled ? 1u : 0u);
Craig Tillera82950e2015-09-22 12:33:20 -0700842 server->channel_filters =
843 gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800844 server->channel_filters[0] = &server_surface_filter;
Craig Tillera82950e2015-09-22 12:33:20 -0700845 if (census_enabled) {
846 server->channel_filters[1] = &grpc_server_census_filter;
847 }
848 for (i = 0; i < filter_count; i++) {
849 server->channel_filters[i + 1u + (census_enabled ? 1u : 0u)] = filters[i];
850 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800851
Craig Tillera82950e2015-09-22 12:33:20 -0700852 server->channel_args = grpc_channel_args_copy(args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800853
854 return server;
855}
856
Craig Tillera82950e2015-09-22 12:33:20 -0700857static int streq(const char *a, const char *b) {
858 if (a == NULL && b == NULL) return 1;
859 if (a == NULL) return 0;
860 if (b == NULL) return 0;
861 return 0 == strcmp(a, b);
Craig Tiller24be0f72015-02-10 14:04:22 -0800862}
863
Craig Tillera82950e2015-09-22 12:33:20 -0700864void *grpc_server_register_method(grpc_server *server, const char *method,
865 const char *host) {
Craig Tiller24be0f72015-02-10 14:04:22 -0800866 registered_method *m;
Craig Tillera82950e2015-09-22 12:33:20 -0700867 if (!method) {
868 gpr_log(GPR_ERROR,
869 "grpc_server_register_method method string cannot be NULL");
870 return NULL;
871 }
872 for (m = server->registered_methods; m; m = m->next) {
873 if (streq(m->method, method) && streq(m->host, host)) {
874 gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
875 host ? host : "*");
Craig Tiller24be0f72015-02-10 14:04:22 -0800876 return NULL;
877 }
Craig Tillera82950e2015-09-22 12:33:20 -0700878 }
879 m = gpr_malloc(sizeof(registered_method));
880 memset(m, 0, sizeof(*m));
881 request_matcher_init(&m->request_matcher, server->max_requested_calls);
882 m->method = gpr_strdup(method);
883 m->host = gpr_strdup(host);
Craig Tiller24be0f72015-02-10 14:04:22 -0800884 m->next = server->registered_methods;
885 server->registered_methods = m;
886 return m;
887}
888
Craig Tillera82950e2015-09-22 12:33:20 -0700889void grpc_server_start(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800890 listener *l;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800891 size_t i;
Craig Tillerf5768a62015-09-22 10:54:34 -0700892 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800893
Craig Tillera82950e2015-09-22 12:33:20 -0700894 server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
895 for (i = 0; i < server->cq_count; i++) {
896 server->pollsets[i] = grpc_cq_pollset(server->cqs[i]);
897 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800898
Craig Tillera82950e2015-09-22 12:33:20 -0700899 for (l = server->listeners; l; l = l->next) {
900 l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count);
901 }
Craig Tillerdfff1b82015-09-21 14:39:57 -0700902
Craig Tillera82950e2015-09-22 12:33:20 -0700903 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800904}
905
Craig Tillera82950e2015-09-22 12:33:20 -0700906void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
907 grpc_transport *transport,
908 grpc_channel_filter const **extra_filters,
909 size_t num_extra_filters, grpc_mdctx *mdctx,
910 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800911 size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700912 grpc_channel_filter const **filters =
913 gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800914 size_t i;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800915 size_t num_registered_methods;
916 size_t alloc;
917 registered_method *rm;
918 channel_registered_method *crm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800919 grpc_channel *channel;
920 channel_data *chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800921 grpc_mdstr *host;
922 grpc_mdstr *method;
923 gpr_uint32 hash;
Craig Tillerf96dfc32015-09-10 14:43:18 -0700924 size_t slots;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800925 gpr_uint32 probes;
926 gpr_uint32 max_probes = 0;
Craig Tillere039f032015-06-25 12:54:23 -0700927 grpc_transport_op op;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800928
Craig Tillera82950e2015-09-22 12:33:20 -0700929 for (i = 0; i < s->channel_filter_count; i++) {
930 filters[i] = s->channel_filters[i];
931 }
932 for (; i < s->channel_filter_count + num_extra_filters; i++) {
933 filters[i] = extra_filters[i - s->channel_filter_count];
934 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800935 filters[i] = &grpc_connected_channel_filter;
936
Craig Tillera82950e2015-09-22 12:33:20 -0700937 for (i = 0; i < s->cq_count; i++) {
938 memset(&op, 0, sizeof(op));
939 op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
940 grpc_transport_perform_op(exec_ctx, transport, &op);
941 }
ctillerd79b4862014-12-17 16:36:59 -0800942
Craig Tillera82950e2015-09-22 12:33:20 -0700943 channel = grpc_channel_create_from_filters(exec_ctx, NULL, filters,
944 num_filters, args, mdctx, 0);
945 chand = (channel_data *)grpc_channel_stack_element(
946 grpc_channel_get_channel_stack(channel), 0)
947 ->channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800948 chand->server = s;
Craig Tillera82950e2015-09-22 12:33:20 -0700949 server_ref(s);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800950 chand->channel = channel;
951
Craig Tiller04cc8be2015-02-10 16:11:22 -0800952 num_registered_methods = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700953 for (rm = s->registered_methods; rm; rm = rm->next) {
954 num_registered_methods++;
955 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800956 /* build a lookup table phrased in terms of mdstr's in this channels context
957 to quickly find registered methods */
Craig Tillera82950e2015-09-22 12:33:20 -0700958 if (num_registered_methods > 0) {
959 slots = 2 * num_registered_methods;
960 alloc = sizeof(channel_registered_method) * slots;
961 chand->registered_methods = gpr_malloc(alloc);
962 memset(chand->registered_methods, 0, alloc);
963 for (rm = s->registered_methods; rm; rm = rm->next) {
964 host = rm->host ? grpc_mdstr_from_string(mdctx, rm->host, 0) : NULL;
965 method = grpc_mdstr_from_string(mdctx, rm->method, 0);
966 hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
967 for (probes = 0; chand->registered_methods[(hash + probes) % slots]
968 .server_registered_method != NULL;
969 probes++)
970 ;
971 if (probes > max_probes) max_probes = probes;
972 crm = &chand->registered_methods[(hash + probes) % slots];
973 crm->server_registered_method = rm;
974 crm->host = host;
975 crm->method = method;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800976 }
Craig Tillera82950e2015-09-22 12:33:20 -0700977 GPR_ASSERT(slots <= GPR_UINT32_MAX);
978 chand->registered_method_slots = (gpr_uint32)slots;
979 chand->registered_method_max_probes = max_probes;
980 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800981
Craig Tillera82950e2015-09-22 12:33:20 -0700982 grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
983 transport);
Craig Tiller7bd5ab12015-02-17 22:29:04 -0800984
Craig Tillera82950e2015-09-22 12:33:20 -0700985 gpr_mu_lock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800986 chand->next = &s->root_channel_data;
987 chand->prev = chand->next->prev;
988 chand->next->prev = chand->prev->next = chand;
Craig Tillera82950e2015-09-22 12:33:20 -0700989 gpr_mu_unlock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800990
Craig Tiller82f9bd82015-09-23 09:31:51 -0700991 gpr_free((void*)filters);
Craig Tiller4b804102015-06-26 16:16:12 -0700992
Craig Tillera82950e2015-09-22 12:33:20 -0700993 GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity");
994 memset(&op, 0, sizeof(op));
Craig Tiller4b804102015-06-26 16:16:12 -0700995 op.set_accept_stream = accept_stream;
996 op.set_accept_stream_user_data = chand;
997 op.on_connectivity_state_change = &chand->channel_connectivity_changed;
998 op.connectivity_state = &chand->connectivity_state;
Craig Tillera82950e2015-09-22 12:33:20 -0700999 op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0;
1000 grpc_transport_perform_op(exec_ctx, transport, &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001001}
1002
Craig Tillera82950e2015-09-22 12:33:20 -07001003void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg,
1004 grpc_cq_completion *storage) {
1005 (void)done_arg;
1006 gpr_free(storage);
murgatroid9900a3dab2015-08-19 11:15:38 -07001007}
1008
Craig Tillera82950e2015-09-22 12:33:20 -07001009static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s,
1010 int success) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001011 grpc_server *server = s;
Craig Tillera82950e2015-09-22 12:33:20 -07001012 gpr_mu_lock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001013 server->listeners_destroyed++;
Craig Tillera82950e2015-09-22 12:33:20 -07001014 maybe_finish_shutdown(exec_ctx, server);
1015 gpr_mu_unlock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001016}
1017
Craig Tillera82950e2015-09-22 12:33:20 -07001018void grpc_server_shutdown_and_notify(grpc_server *server,
1019 grpc_completion_queue *cq, void *tag) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001020 listener *l;
Craig Tillerbce999f2015-05-27 09:55:51 -07001021 shutdown_tag *sdt;
Craig Tillerff3ae682015-06-29 17:44:04 -07001022 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001023 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001024
Craig Tillera82950e2015-09-22 12:33:20 -07001025 GRPC_SERVER_LOG_SHUTDOWN(GPR_INFO, server, cq, tag);
Craig Tiller7156fca2015-07-15 13:54:20 -07001026
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001027 /* lock, and gather up some stuff to do */
Craig Tillera82950e2015-09-22 12:33:20 -07001028 gpr_mu_lock(&server->mu_global);
1029 grpc_cq_begin_op(cq);
1030 if (server->shutdown_published) {
1031 grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL,
1032 gpr_malloc(sizeof(grpc_cq_completion)));
1033 gpr_mu_unlock(&server->mu_global);
1034 goto done;
1035 }
1036 server->shutdown_tags =
1037 gpr_realloc(server->shutdown_tags,
1038 sizeof(shutdown_tag) * (server->num_shutdown_tags + 1));
Craig Tillerbce999f2015-05-27 09:55:51 -07001039 sdt = &server->shutdown_tags[server->num_shutdown_tags++];
1040 sdt->tag = tag;
1041 sdt->cq = cq;
Craig Tillera82950e2015-09-22 12:33:20 -07001042 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1043 gpr_mu_unlock(&server->mu_global);
1044 goto done;
1045 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001046
Craig Tillera82950e2015-09-22 12:33:20 -07001047 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
Craig Tillerab54f792015-07-08 08:34:20 -07001048
Craig Tillera82950e2015-09-22 12:33:20 -07001049 channel_broadcaster_init(server, &broadcaster);
nnoble0c475f02014-12-05 15:37:39 -08001050
Craig Tillerbd217572015-02-11 18:10:56 -08001051 /* collect all unregistered then registered calls */
Craig Tillera82950e2015-09-22 12:33:20 -07001052 gpr_mu_lock(&server->mu_call);
1053 kill_pending_work_locked(&exec_ctx, server);
1054 gpr_mu_unlock(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001055
Craig Tillera82950e2015-09-22 12:33:20 -07001056 gpr_atm_rel_store(&server->shutdown_flag, 1);
1057 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
Craig Tillera82950e2015-09-22 12:33:20 -07001076 gpr_mu_lock(&server->mu_global);
1077 channel_broadcaster_init(server, &broadcaster);
1078 gpr_mu_unlock(&server->mu_global);
Craig Tillerafa2d632015-05-26 16:39:13 -07001079
Craig Tillera82950e2015-09-22 12:33:20 -07001080 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1);
1081 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerafa2d632015-05-26 16:39:13 -07001082}
1083
Craig Tillera82950e2015-09-22 12:33:20 -07001084void grpc_server_destroy(grpc_server *server) {
Craig Tilleraec96aa2015-04-07 14:32:15 -07001085 listener *l;
Craig Tillerf5768a62015-09-22 10:54:34 -07001086 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller872af022015-04-24 15:57:52 -07001087
Craig Tillera82950e2015-09-22 12:33:20 -07001088 gpr_mu_lock(&server->mu_global);
1089 GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners);
1090 GPR_ASSERT(server->listeners_destroyed == num_listeners(server));
Craig Tilleraec96aa2015-04-07 14:32:15 -07001091
Craig Tillera82950e2015-09-22 12:33:20 -07001092 while (server->listeners) {
1093 l = server->listeners;
1094 server->listeners = l->next;
1095 gpr_free(l);
1096 }
Craig Tilleraec96aa2015-04-07 14:32:15 -07001097
Craig Tillera82950e2015-09-22 12:33:20 -07001098 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001099
Craig Tillera82950e2015-09-22 12:33:20 -07001100 server_unref(&exec_ctx, server);
1101 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001102}
1103
Craig Tillera82950e2015-09-22 12:33:20 -07001104void grpc_server_add_listener(
1105 grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1106 void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1107 grpc_pollset **pollsets, size_t pollset_count),
1108 void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1109 grpc_closure *on_done)) {
1110 listener *l = gpr_malloc(sizeof(listener));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001111 l->arg = arg;
1112 l->start = start;
1113 l->destroy = destroy;
1114 l->next = server->listeners;
1115 server->listeners = l;
1116}
1117
Craig Tillera82950e2015-09-22 12:33:20 -07001118static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1119 grpc_server *server,
1120 requested_call *rc) {
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001121 call_data *calld = NULL;
Craig Tiller729b35a2015-07-13 12:36:47 -07001122 request_matcher *request_matcher = NULL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001123 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -07001124 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1125 fail_call(exec_ctx, server, rc);
1126 return GRPC_CALL_OK;
1127 }
1128 request_id = gpr_stack_lockfree_pop(server->request_freelist);
1129 if (request_id == -1) {
1130 /* out of request ids: just fail this one */
1131 fail_call(exec_ctx, server, rc);
1132 return GRPC_CALL_OK;
1133 }
1134 switch (rc->type) {
Craig Tiller04cc8be2015-02-10 16:11:22 -08001135 case BATCH_CALL:
Craig Tiller729b35a2015-07-13 12:36:47 -07001136 request_matcher = &server->unregistered_request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001137 break;
1138 case REGISTERED_CALL:
Craig Tiller729b35a2015-07-13 12:36:47 -07001139 request_matcher = &rc->data.registered.registered_method->request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001140 break;
Craig Tillera82950e2015-09-22 12:33:20 -07001141 }
Craig Tiller45724b32015-09-22 10:42:19 -07001142 server->requested_calls[request_id] = *rc;
Craig Tillera82950e2015-09-22 12:33:20 -07001143 gpr_free(rc);
1144 if (gpr_stack_lockfree_push(request_matcher->requests, request_id)) {
1145 /* this was the first queued request: we need to lock and start
1146 matching calls */
1147 gpr_mu_lock(&server->mu_call);
1148 while ((calld = request_matcher->pending_head) != NULL) {
1149 request_id = gpr_stack_lockfree_pop(request_matcher->requests);
1150 if (request_id == -1) break;
1151 request_matcher->pending_head = calld->pending_next;
1152 gpr_mu_unlock(&server->mu_call);
1153 gpr_mu_lock(&calld->mu_state);
1154 if (calld->state == ZOMBIED) {
1155 gpr_mu_unlock(&calld->mu_state);
1156 grpc_closure_init(
1157 &calld->kill_zombie_closure, kill_zombie,
1158 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
1159 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, 1);
1160 } else {
1161 GPR_ASSERT(calld->state == PENDING);
1162 calld->state = ACTIVATED;
1163 gpr_mu_unlock(&calld->mu_state);
1164 begin_call(exec_ctx, server, calld,
1165 &server->requested_calls[request_id]);
1166 }
1167 gpr_mu_lock(&server->mu_call);
Craig Tiller45724b32015-09-22 10:42:19 -07001168 }
Craig Tillera82950e2015-09-22 12:33:20 -07001169 gpr_mu_unlock(&server->mu_call);
1170 }
Craig Tiller6a006ce2015-07-13 16:25:40 -07001171 return GRPC_CALL_OK;
Craig Tillercce17ac2015-01-20 09:29:28 -08001172}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001173
Craig Tillera82950e2015-09-22 12:33:20 -07001174grpc_call_error grpc_server_request_call(
1175 grpc_server *server, grpc_call **call, grpc_call_details *details,
1176 grpc_metadata_array *initial_metadata,
1177 grpc_completion_queue *cq_bound_to_call,
1178 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001179 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001180 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001181 requested_call *rc = gpr_malloc(sizeof(*rc));
1182 GRPC_SERVER_LOG_REQUEST_CALL(GPR_INFO, server, call, details,
1183 initial_metadata, cq_bound_to_call,
1184 cq_for_notification, tag);
1185 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1186 gpr_free(rc);
1187 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1188 goto done;
1189 }
1190 grpc_cq_begin_op(cq_for_notification);
Craig Tiller9928d392015-08-18 09:40:24 -07001191 details->reserved = NULL;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001192 rc->type = BATCH_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001193 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001194 rc->tag = tag;
1195 rc->cq_bound_to_call = cq_bound_to_call;
1196 rc->cq_for_notification = cq_for_notification;
1197 rc->call = call;
1198 rc->data.batch.details = details;
1199 rc->data.batch.initial_metadata = initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -07001200 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001201done:
Craig Tillera82950e2015-09-22 12:33:20 -07001202 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001203 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001204}
1205
Craig Tillera82950e2015-09-22 12:33:20 -07001206grpc_call_error grpc_server_request_registered_call(
1207 grpc_server *server, void *rm, grpc_call **call, gpr_timespec *deadline,
1208 grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload,
1209 grpc_completion_queue *cq_bound_to_call,
1210 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001211 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001212 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001213 requested_call *rc = gpr_malloc(sizeof(*rc));
Craig Tiller20bc56d2015-02-12 09:02:56 -08001214 registered_method *registered_method = rm;
Craig Tillera82950e2015-09-22 12:33:20 -07001215 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1216 gpr_free(rc);
1217 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1218 goto done;
1219 }
1220 grpc_cq_begin_op(cq_for_notification);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001221 rc->type = REGISTERED_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001222 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001223 rc->tag = tag;
1224 rc->cq_bound_to_call = cq_bound_to_call;
1225 rc->cq_for_notification = cq_for_notification;
1226 rc->call = call;
1227 rc->data.registered.registered_method = registered_method;
1228 rc->data.registered.deadline = deadline;
1229 rc->data.registered.initial_metadata = initial_metadata;
1230 rc->data.registered.optional_payload = optional_payload;
Craig Tillera82950e2015-09-22 12:33:20 -07001231 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001232done:
Craig Tillera82950e2015-09-22 12:33:20 -07001233 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001234 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001235}
1236
Craig Tillera82950e2015-09-22 12:33:20 -07001237static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx,
1238 grpc_call *call, int success,
1239 void *tag);
1240static void publish_was_not_set(grpc_exec_ctx *exec_ctx, grpc_call *call,
1241 int success, void *tag) {
1242 abort();
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001243}
Craig Tiller24be0f72015-02-10 14:04:22 -08001244
Craig Tillera82950e2015-09-22 12:33:20 -07001245static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
Craig Tiller166e2502015-02-03 20:14:41 -08001246 gpr_slice slice = value->slice;
Craig Tillera82950e2015-09-22 12:33:20 -07001247 size_t len = GPR_SLICE_LENGTH(slice);
Craig Tiller166e2502015-02-03 20:14:41 -08001248
Craig Tillera82950e2015-09-22 12:33:20 -07001249 if (len + 1 > *capacity) {
1250 *capacity = GPR_MAX(len + 1, *capacity * 2);
1251 *dest = gpr_realloc(*dest, *capacity);
1252 }
1253 memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
Craig Tiller166e2502015-02-03 20:14:41 -08001254}
1255
Craig Tillera82950e2015-09-22 12:33:20 -07001256static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1257 call_data *calld, requested_call *rc) {
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001258 grpc_ioreq_completion_func publish = publish_was_not_set;
Craig Tiller24be0f72015-02-10 14:04:22 -08001259 grpc_ioreq req[2];
1260 grpc_ioreq *r = req;
1261
1262 /* called once initial metadata has been read by the call, but BEFORE
1263 the ioreq to fetch it out of the call has been executed.
1264 This means metadata related fields can be relied on in calld, but to
1265 fill in the metadata array passed by the client, we need to perform
1266 an ioreq op, that should complete immediately. */
1267
Craig Tillera82950e2015-09-22 12:33:20 -07001268 grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001269 *rc->call = calld->call;
1270 calld->cq_new = rc->cq_for_notification;
Craig Tillera82950e2015-09-22 12:33:20 -07001271 switch (rc->type) {
Craig Tiller24be0f72015-02-10 14:04:22 -08001272 case BATCH_CALL:
Craig Tillera82950e2015-09-22 12:33:20 -07001273 GPR_ASSERT(calld->host != NULL);
1274 GPR_ASSERT(calld->path != NULL);
1275 cpstr(&rc->data.batch.details->host,
1276 &rc->data.batch.details->host_capacity, calld->host);
1277 cpstr(&rc->data.batch.details->method,
1278 &rc->data.batch.details->method_capacity, calld->path);
Masood Malekghassemibf177c82015-04-27 12:14:38 -07001279 rc->data.batch.details->deadline = calld->deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -08001280 r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
1281 r->data.recv_metadata = rc->data.batch.initial_metadata;
David Garcia Quintasb8f54502015-06-15 16:19:10 -07001282 r->flags = 0;
Craig Tiller24be0f72015-02-10 14:04:22 -08001283 r++;
1284 publish = publish_registered_or_batch;
1285 break;
1286 case REGISTERED_CALL:
1287 *rc->data.registered.deadline = calld->deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -08001288 r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
1289 r->data.recv_metadata = rc->data.registered.initial_metadata;
David Garcia Quintasb8f54502015-06-15 16:19:10 -07001290 r->flags = 0;
Craig Tiller24be0f72015-02-10 14:04:22 -08001291 r++;
Craig Tillera82950e2015-09-22 12:33:20 -07001292 if (rc->data.registered.optional_payload) {
1293 r->op = GRPC_IOREQ_RECV_MESSAGE;
1294 r->data.recv_message = rc->data.registered.optional_payload;
1295 r->flags = 0;
1296 r++;
1297 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001298 publish = publish_registered_or_batch;
1299 break;
Craig Tillera82950e2015-09-22 12:33:20 -07001300 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001301
Craig Tillera82950e2015-09-22 12:33:20 -07001302 GRPC_CALL_INTERNAL_REF(calld->call, "server");
1303 grpc_call_start_ioreq_and_call_back(exec_ctx, calld->call, req,
1304 (size_t)(r - req), publish, rc);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001305}
1306
Craig Tillera82950e2015-09-22 12:33:20 -07001307static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
1308 grpc_cq_completion *c) {
Craig Tiller6a006ce2015-07-13 16:25:40 -07001309 requested_call *rc = req;
1310 grpc_server *server = rc->server;
1311
Craig Tillera82950e2015-09-22 12:33:20 -07001312 if (rc >= server->requested_calls &&
1313 rc < server->requested_calls + server->max_requested_calls) {
1314 GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
1315 gpr_stack_lockfree_push(server->request_freelist,
1316 (int)(rc - server->requested_calls));
1317 } else {
1318 gpr_free(req);
1319 }
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001320
Craig Tillera82950e2015-09-22 12:33:20 -07001321 server_unref(exec_ctx, server);
Craig Tiller24be0f72015-02-10 14:04:22 -08001322}
1323
Craig Tillera82950e2015-09-22 12:33:20 -07001324static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1325 requested_call *rc) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001326 *rc->call = NULL;
Craig Tillera82950e2015-09-22 12:33:20 -07001327 switch (rc->type) {
Craig Tiller24be0f72015-02-10 14:04:22 -08001328 case BATCH_CALL:
Craig Tiller24be0f72015-02-10 14:04:22 -08001329 rc->data.batch.initial_metadata->count = 0;
Craig Tiller24be0f72015-02-10 14:04:22 -08001330 break;
1331 case REGISTERED_CALL:
Craig Tiller24be0f72015-02-10 14:04:22 -08001332 rc->data.registered.initial_metadata->count = 0;
Craig Tiller24be0f72015-02-10 14:04:22 -08001333 break;
Craig Tillera82950e2015-09-22 12:33:20 -07001334 }
1335 server_ref(server);
1336 grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
1337 done_request_event, rc, &rc->completion);
Craig Tiller24be0f72015-02-10 14:04:22 -08001338}
1339
Craig Tillera82950e2015-09-22 12:33:20 -07001340static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx,
1341 grpc_call *call, int success,
1342 void *prc) {
1343 grpc_call_element *elem =
1344 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001345 requested_call *rc = prc;
Craig Tiller20bc56d2015-02-12 09:02:56 -08001346 call_data *calld = elem->call_data;
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001347 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001348 server_ref(chand->server);
1349 grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event,
1350 rc, &rc->completion);
1351 GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server");
Craig Tiller24be0f72015-02-10 14:04:22 -08001352}
1353
Craig Tillera82950e2015-09-22 12:33:20 -07001354const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001355 return server->channel_args;
Craig Tiller190d3602015-02-18 09:23:38 -08001356}
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001357
Craig Tillera82950e2015-09-22 12:33:20 -07001358int grpc_server_has_open_connections(grpc_server *server) {
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001359 int r;
Craig Tillera82950e2015-09-22 12:33:20 -07001360 gpr_mu_lock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001361 r = server->root_channel_data.next != &server->root_channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001362 gpr_mu_unlock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001363 return r;
1364}