blob: 080734e9d59fd1bd4019ef76e19326896a4895d1 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Bogdan Drutuaff40662016-01-25 10:21:38 -08003 * Copyright 2015-2016, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Craig Tiller9533d042016-03-25 17:11:06 -070034#include "src/core/lib/surface/server.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080035
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
Craig Tiller9533d042016-03-25 17:11:06 -070045#include "src/core/lib/channel/channel_args.h"
46#include "src/core/lib/channel/connected_channel.h"
47#include "src/core/lib/iomgr/iomgr.h"
48#include "src/core/lib/support/stack_lockfree.h"
49#include "src/core/lib/support/string.h"
50#include "src/core/lib/surface/api_trace.h"
51#include "src/core/lib/surface/call.h"
52#include "src/core/lib/surface/channel.h"
53#include "src/core/lib/surface/completion_queue.h"
54#include "src/core/lib/surface/init.h"
55#include "src/core/lib/transport/metadata.h"
56#include "src/core/lib/transport/static_metadata.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080057
Craig Tillera82950e2015-09-22 12:33:20 -070058typedef struct listener {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080059 void *arg;
Craig Tillera82950e2015-09-22 12:33:20 -070060 void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
61 grpc_pollset **pollsets, size_t pollset_count);
62 void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
63 grpc_closure *closure);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080064 struct listener *next;
Craig Tillerdfff1b82015-09-21 14:39:57 -070065 grpc_closure destroy_done;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080066} listener;
67
68typedef struct call_data call_data;
69typedef struct channel_data channel_data;
Craig Tiller24be0f72015-02-10 14:04:22 -080070typedef struct registered_method registered_method;
71
Craig Tillera82950e2015-09-22 12:33:20 -070072typedef struct {
Craig Tiller24be0f72015-02-10 14:04:22 -080073 call_data *next;
74 call_data *prev;
75} call_link;
76
Craig Tillera82950e2015-09-22 12:33:20 -070077typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type;
Craig Tiller24be0f72015-02-10 14:04:22 -080078
Craig Tillera82950e2015-09-22 12:33:20 -070079typedef struct requested_call {
Craig Tiller24be0f72015-02-10 14:04:22 -080080 requested_call_type type;
81 void *tag;
Craig Tiller6a006ce2015-07-13 16:25:40 -070082 grpc_server *server;
Craig Tillerf9e6adf2015-05-06 11:45:59 -070083 grpc_completion_queue *cq_bound_to_call;
84 grpc_completion_queue *cq_for_notification;
85 grpc_call **call;
Craig Tiller97fc6a32015-07-08 15:31:35 -070086 grpc_cq_completion completion;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -080087 grpc_metadata_array *initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -070088 union {
89 struct {
Craig Tiller24be0f72015-02-10 14:04:22 -080090 grpc_call_details *details;
Craig Tiller24be0f72015-02-10 14:04:22 -080091 } batch;
Craig Tillera82950e2015-09-22 12:33:20 -070092 struct {
Craig Tiller24be0f72015-02-10 14:04:22 -080093 registered_method *registered_method;
94 gpr_timespec *deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -080095 grpc_byte_buffer **optional_payload;
96 } registered;
97 } data;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -080098 grpc_closure publish;
Craig Tiller24be0f72015-02-10 14:04:22 -080099} requested_call;
100
Craig Tillera82950e2015-09-22 12:33:20 -0700101typedef struct channel_registered_method {
Craig Tiller24be0f72015-02-10 14:04:22 -0800102 registered_method *server_registered_method;
103 grpc_mdstr *method;
104 grpc_mdstr *host;
105} channel_registered_method;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800106
Craig Tillera82950e2015-09-22 12:33:20 -0700107struct channel_data {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800108 grpc_server *server;
Craig Tillere039f032015-06-25 12:54:23 -0700109 grpc_connectivity_state connectivity_state;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800110 grpc_channel *channel;
111 /* linked list of all channels on a server */
112 channel_data *next;
113 channel_data *prev;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800114 channel_registered_method *registered_methods;
Craig Tiller7536af02015-12-22 13:49:30 -0800115 uint32_t registered_method_slots;
116 uint32_t registered_method_max_probes;
Craig Tiller33825112015-09-18 07:44:19 -0700117 grpc_closure finish_destroy_channel_closure;
118 grpc_closure channel_connectivity_changed;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800119};
120
Craig Tillera82950e2015-09-22 12:33:20 -0700121typedef struct shutdown_tag {
Craig Tillerbce999f2015-05-27 09:55:51 -0700122 void *tag;
123 grpc_completion_queue *cq;
Craig Tiller97fc6a32015-07-08 15:31:35 -0700124 grpc_cq_completion completion;
Craig Tillerbce999f2015-05-27 09:55:51 -0700125} shutdown_tag;
126
Craig Tillera82950e2015-09-22 12:33:20 -0700127typedef enum {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800128 /* waiting for metadata */
129 NOT_STARTED,
130 /* inital metadata read, not flow controlled in yet */
131 PENDING,
132 /* flow controlled in, on completion queue */
133 ACTIVATED,
134 /* cancelled before being queued */
135 ZOMBIED
136} call_state;
137
Craig Tiller729b35a2015-07-13 12:36:47 -0700138typedef struct request_matcher request_matcher;
139
Craig Tillera82950e2015-09-22 12:33:20 -0700140struct call_data {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800141 grpc_call *call;
142
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700143 /** protects state */
144 gpr_mu mu_state;
145 /** the current state of a call - see call_state */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800146 call_state state;
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700147
Craig Tillercce17ac2015-01-20 09:29:28 -0800148 grpc_mdstr *path;
149 grpc_mdstr *host;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700150 gpr_timespec deadline;
Craig Tillercce17ac2015-01-20 09:29:28 -0800151
Craig Tiller20bc56d2015-02-12 09:02:56 -0800152 grpc_completion_queue *cq_new;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800153
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800154 grpc_metadata_batch *recv_initial_metadata;
155 grpc_metadata_array initial_metadata;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700156
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800157 grpc_closure got_initial_metadata;
158 grpc_closure server_on_recv_initial_metadata;
Craig Tiller33825112015-09-18 07:44:19 -0700159 grpc_closure kill_zombie_closure;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800160 grpc_closure *on_done_recv_initial_metadata;
David Garcia Quintas284488b2015-05-28 16:27:39 -0700161
Craig Tiller729b35a2015-07-13 12:36:47 -0700162 call_data *pending_next;
163};
164
Craig Tillera82950e2015-09-22 12:33:20 -0700165struct request_matcher {
Craig Tiller729b35a2015-07-13 12:36:47 -0700166 call_data *pending_head;
167 call_data *pending_tail;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700168 gpr_stack_lockfree *requests;
Craig Tiller729b35a2015-07-13 12:36:47 -0700169};
170
Craig Tillera82950e2015-09-22 12:33:20 -0700171struct registered_method {
Craig Tiller729b35a2015-07-13 12:36:47 -0700172 char *method;
173 char *host;
174 request_matcher request_matcher;
175 registered_method *next;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800176};
177
Craig Tillera82950e2015-09-22 12:33:20 -0700178typedef struct {
Craig Tillerff3ae682015-06-29 17:44:04 -0700179 grpc_channel **channels;
180 size_t num_channels;
181} channel_broadcaster;
182
Craig Tillera82950e2015-09-22 12:33:20 -0700183struct grpc_server {
Craig Tiller729b35a2015-07-13 12:36:47 -0700184 grpc_channel_args *channel_args;
185
186 grpc_completion_queue **cqs;
187 grpc_pollset **pollsets;
188 size_t cq_count;
189
190 /* The two following mutexes control access to server-state
191 mu_global controls access to non-call-related state (e.g., channel state)
192 mu_call controls access to call-related state (e.g., the call lists)
193
194 If they are ever required to be nested, you must lock mu_global
195 before mu_call. This is currently used in shutdown processing
196 (grpc_server_shutdown_and_notify and maybe_finish_shutdown) */
Craig Tillera82950e2015-09-22 12:33:20 -0700197 gpr_mu mu_global; /* mutex for server and channel state */
198 gpr_mu mu_call; /* mutex for call-specific state */
Craig Tiller729b35a2015-07-13 12:36:47 -0700199
200 registered_method *registered_methods;
201 request_matcher unregistered_request_matcher;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700202 /** free list of available requested_calls indices */
203 gpr_stack_lockfree *request_freelist;
204 /** requested call backing data */
205 requested_call *requested_calls;
Craig Tiller32ca48c2015-09-10 11:47:15 -0700206 size_t max_requested_calls;
Craig Tiller729b35a2015-07-13 12:36:47 -0700207
Craig Tiller6a006ce2015-07-13 16:25:40 -0700208 gpr_atm shutdown_flag;
Craig Tiller7536af02015-12-22 13:49:30 -0800209 uint8_t shutdown_published;
Craig Tiller729b35a2015-07-13 12:36:47 -0700210 size_t num_shutdown_tags;
211 shutdown_tag *shutdown_tags;
212
213 channel_data root_channel_data;
214
215 listener *listeners;
216 int listeners_destroyed;
217 gpr_refcount internal_refcount;
218
219 /** when did we print the last shutdown progress message */
220 gpr_timespec last_shutdown_message_time;
221};
222
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800223#define SERVER_FROM_CALL_ELEM(elem) \
224 (((channel_data *)(elem)->channel_data)->server)
225
Craig Tillera82950e2015-09-22 12:33:20 -0700226static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
227 call_data *calld, requested_call *rc);
228static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
229 requested_call *rc);
Vijay Pai8931cdd2015-06-17 12:42:17 -0700230/* Before calling maybe_finish_shutdown, we must hold mu_global and not
231 hold mu_call */
Craig Tillera82950e2015-09-22 12:33:20 -0700232static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server);
Craig Tiller24be0f72015-02-10 14:04:22 -0800233
Craig Tiller729b35a2015-07-13 12:36:47 -0700234/*
235 * channel broadcaster
236 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700237
238/* assumes server locked */
Craig Tillera82950e2015-09-22 12:33:20 -0700239static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700240 channel_data *c;
241 size_t count = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700242 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
243 count++;
244 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700245 cb->num_channels = count;
Craig Tillera82950e2015-09-22 12:33:20 -0700246 cb->channels = gpr_malloc(sizeof(*cb->channels) * cb->num_channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700247 count = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700248 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
249 cb->channels[count++] = c->channel;
250 GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast");
251 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700252}
253
Craig Tillera82950e2015-09-22 12:33:20 -0700254struct shutdown_cleanup_args {
Craig Tiller33825112015-09-18 07:44:19 -0700255 grpc_closure closure;
Craig Tillerff3ae682015-06-29 17:44:04 -0700256 gpr_slice slice;
257};
258
Craig Tillera82950e2015-09-22 12:33:20 -0700259static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg,
Craig Tiller6c396862016-01-28 13:53:40 -0800260 bool iomgr_status_ignored) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700261 struct shutdown_cleanup_args *a = arg;
Craig Tillera82950e2015-09-22 12:33:20 -0700262 gpr_slice_unref(a->slice);
263 gpr_free(a);
Craig Tillerff3ae682015-06-29 17:44:04 -0700264}
265
Craig Tillera82950e2015-09-22 12:33:20 -0700266static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
267 int send_goaway, int send_disconnect) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700268 grpc_transport_op op;
269 struct shutdown_cleanup_args *sc;
270 grpc_channel_element *elem;
271
Craig Tillera82950e2015-09-22 12:33:20 -0700272 memset(&op, 0, sizeof(op));
Craig Tillerff3ae682015-06-29 17:44:04 -0700273 op.send_goaway = send_goaway;
Craig Tillera82950e2015-09-22 12:33:20 -0700274 sc = gpr_malloc(sizeof(*sc));
275 sc->slice = gpr_slice_from_copied_string("Server shutdown");
Craig Tillerff3ae682015-06-29 17:44:04 -0700276 op.goaway_message = &sc->slice;
277 op.goaway_status = GRPC_STATUS_OK;
278 op.disconnect = send_disconnect;
Craig Tillera82950e2015-09-22 12:33:20 -0700279 grpc_closure_init(&sc->closure, shutdown_cleanup, sc);
Craig Tillerff3ae682015-06-29 17:44:04 -0700280 op.on_consumed = &sc->closure;
281
Craig Tillera82950e2015-09-22 12:33:20 -0700282 elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
283 elem->filter->start_transport_op(exec_ctx, elem, &op);
Craig Tillerff3ae682015-06-29 17:44:04 -0700284}
285
Craig Tillera82950e2015-09-22 12:33:20 -0700286static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx,
287 channel_broadcaster *cb,
288 int send_goaway,
289 int force_disconnect) {
Craig Tillerff3ae682015-06-29 17:44:04 -0700290 size_t i;
291
Craig Tillera82950e2015-09-22 12:33:20 -0700292 for (i = 0; i < cb->num_channels; i++) {
293 send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect);
294 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast");
295 }
296 gpr_free(cb->channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700297}
298
Craig Tiller729b35a2015-07-13 12:36:47 -0700299/*
300 * request_matcher
301 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700302
Craig Tiller8dc09712015-09-24 13:58:16 -0700303static void request_matcher_init(request_matcher *rm, size_t entries) {
Craig Tillerb9d35962015-09-11 13:31:16 -0700304 memset(rm, 0, sizeof(*rm));
305 rm->requests = gpr_stack_lockfree_create(entries);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800306}
307
Craig Tillerb9d35962015-09-11 13:31:16 -0700308static void request_matcher_destroy(request_matcher *rm) {
309 GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests) == -1);
310 gpr_stack_lockfree_destroy(rm->requests);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800311}
312
Craig Tiller6c396862016-01-28 13:53:40 -0800313static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, bool success) {
Craig Tillera82950e2015-09-22 12:33:20 -0700314 grpc_call_destroy(grpc_call_from_top_element(elem));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800315}
316
Craig Tiller8dc09712015-09-24 13:58:16 -0700317static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx,
318 request_matcher *rm) {
Craig Tillerb9d35962015-09-11 13:31:16 -0700319 while (rm->pending_head) {
320 call_data *calld = rm->pending_head;
321 rm->pending_head = calld->pending_next;
Craig Tillera82950e2015-09-22 12:33:20 -0700322 gpr_mu_lock(&calld->mu_state);
323 calld->state = ZOMBIED;
324 gpr_mu_unlock(&calld->mu_state);
325 grpc_closure_init(
326 &calld->kill_zombie_closure, kill_zombie,
327 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
Craig Tiller6c396862016-01-28 13:53:40 -0800328 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillera82950e2015-09-22 12:33:20 -0700329 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800330}
331
Craig Tillera82950e2015-09-22 12:33:20 -0700332static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx,
333 grpc_server *server,
334 request_matcher *rm) {
Craig Tiller1191e212015-07-30 14:49:02 -0700335 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -0700336 while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) {
337 fail_call(exec_ctx, server, &server->requested_calls[request_id]);
338 }
Craig Tiller1191e212015-07-30 14:49:02 -0700339}
340
Craig Tiller729b35a2015-07-13 12:36:47 -0700341/*
342 * server proper
343 */
344
Craig Tillera82950e2015-09-22 12:33:20 -0700345static void server_ref(grpc_server *server) {
346 gpr_ref(&server->internal_refcount);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800347}
348
Craig Tillera82950e2015-09-22 12:33:20 -0700349static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800350 registered_method *rm;
Craig Tiller89504612015-04-27 11:48:46 -0700351 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700352 grpc_channel_args_destroy(server->channel_args);
353 gpr_mu_destroy(&server->mu_global);
354 gpr_mu_destroy(&server->mu_call);
Craig Tillera82950e2015-09-22 12:33:20 -0700355 while ((rm = server->registered_methods) != NULL) {
356 server->registered_methods = rm->next;
357 request_matcher_destroy(&rm->request_matcher);
358 gpr_free(rm->method);
359 gpr_free(rm->host);
360 gpr_free(rm);
361 }
362 for (i = 0; i < server->cq_count; i++) {
363 GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server");
364 }
365 request_matcher_destroy(&server->unregistered_request_matcher);
366 gpr_stack_lockfree_destroy(server->request_freelist);
367 gpr_free(server->cqs);
368 gpr_free(server->pollsets);
369 gpr_free(server->shutdown_tags);
370 gpr_free(server->requested_calls);
371 gpr_free(server);
Craig Tilleree945e82015-05-26 16:15:34 -0700372}
373
Craig Tillera82950e2015-09-22 12:33:20 -0700374static void server_unref(grpc_exec_ctx *exec_ctx, grpc_server *server) {
375 if (gpr_unref(&server->internal_refcount)) {
376 server_delete(exec_ctx, server);
377 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800378}
379
Craig Tillera82950e2015-09-22 12:33:20 -0700380static int is_channel_orphaned(channel_data *chand) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800381 return chand->next == chand;
382}
383
Craig Tillera82950e2015-09-22 12:33:20 -0700384static void orphan_channel(channel_data *chand) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800385 chand->next->prev = chand->prev;
386 chand->prev->next = chand->next;
387 chand->next = chand->prev = chand;
388}
389
Craig Tillera82950e2015-09-22 12:33:20 -0700390static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd,
Craig Tiller6c396862016-01-28 13:53:40 -0800391 bool success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800392 channel_data *chand = cd;
393 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700394 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server");
395 server_unref(exec_ctx, server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800396}
397
Craig Tillera82950e2015-09-22 12:33:20 -0700398static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) {
399 if (is_channel_orphaned(chand)) return;
400 GPR_ASSERT(chand->server != NULL);
401 orphan_channel(chand);
402 server_ref(chand->server);
403 maybe_finish_shutdown(exec_ctx, chand->server);
David Garcia Quintas284488b2015-05-28 16:27:39 -0700404 chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
405 chand->finish_destroy_channel_closure.cb_arg = chand;
Craig Tillerd7f12e32016-03-03 10:08:31 -0800406
407 grpc_transport_op op;
408 memset(&op, 0, sizeof(op));
409 op.set_accept_stream = true;
410 op.on_consumed = &chand->finish_destroy_channel_closure;
411 grpc_channel_next_op(exec_ctx,
412 grpc_channel_stack_element(
413 grpc_channel_get_channel_stack(chand->channel), 0),
414 &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800415}
416
Craig Tillera82950e2015-09-22 12:33:20 -0700417static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server,
Craig Tiller8dc09712015-09-24 13:58:16 -0700418 grpc_call_element *elem, request_matcher *rm) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800419 call_data *calld = elem->call_data;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700420 int request_id;
421
Craig Tillera82950e2015-09-22 12:33:20 -0700422 if (gpr_atm_acq_load(&server->shutdown_flag)) {
423 gpr_mu_lock(&calld->mu_state);
424 calld->state = ZOMBIED;
425 gpr_mu_unlock(&calld->mu_state);
426 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller6c396862016-01-28 13:53:40 -0800427 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillera82950e2015-09-22 12:33:20 -0700428 return;
429 }
Craig Tiller45724b32015-09-22 10:42:19 -0700430
Craig Tillerb9d35962015-09-11 13:31:16 -0700431 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -0700432 if (request_id == -1) {
433 gpr_mu_lock(&server->mu_call);
434 gpr_mu_lock(&calld->mu_state);
435 calld->state = PENDING;
436 gpr_mu_unlock(&calld->mu_state);
Craig Tillerb9d35962015-09-11 13:31:16 -0700437 if (rm->pending_head == NULL) {
438 rm->pending_tail = rm->pending_head = calld;
Craig Tillera82950e2015-09-22 12:33:20 -0700439 } else {
Craig Tillerb9d35962015-09-11 13:31:16 -0700440 rm->pending_tail->pending_next = calld;
441 rm->pending_tail = calld;
Craig Tiller45724b32015-09-22 10:42:19 -0700442 }
Craig Tillera82950e2015-09-22 12:33:20 -0700443 calld->pending_next = NULL;
444 gpr_mu_unlock(&server->mu_call);
445 } else {
446 gpr_mu_lock(&calld->mu_state);
447 calld->state = ACTIVATED;
448 gpr_mu_unlock(&calld->mu_state);
449 begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
450 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800451}
452
Craig Tillera82950e2015-09-22 12:33:20 -0700453static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800454 channel_data *chand = elem->channel_data;
455 call_data *calld = elem->call_data;
456 grpc_server *server = chand->server;
Craig Tiller7536af02015-12-22 13:49:30 -0800457 uint32_t i;
458 uint32_t hash;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800459 channel_registered_method *rm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800460
Craig Tillera82950e2015-09-22 12:33:20 -0700461 if (chand->registered_methods && calld->path && calld->host) {
462 /* TODO(ctiller): unify these two searches */
463 /* check for an exact match with host */
464 hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
465 for (i = 0; i <= chand->registered_method_max_probes; i++) {
466 rm = &chand->registered_methods[(hash + i) %
467 chand->registered_method_slots];
468 if (!rm) break;
469 if (rm->host != calld->host) continue;
470 if (rm->method != calld->path) continue;
471 finish_start_new_rpc(exec_ctx, server, elem,
472 &rm->server_registered_method->request_matcher);
473 return;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800474 }
Craig Tillera82950e2015-09-22 12:33:20 -0700475 /* check for a wildcard method definition (no host set) */
476 hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
477 for (i = 0; i <= chand->registered_method_max_probes; i++) {
478 rm = &chand->registered_methods[(hash + i) %
479 chand->registered_method_slots];
480 if (!rm) break;
481 if (rm->host != NULL) continue;
482 if (rm->method != calld->path) continue;
483 finish_start_new_rpc(exec_ctx, server, elem,
484 &rm->server_registered_method->request_matcher);
485 return;
486 }
487 }
488 finish_start_new_rpc(exec_ctx, server, elem,
489 &server->unregistered_request_matcher);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800490}
491
Craig Tillera82950e2015-09-22 12:33:20 -0700492static int num_listeners(grpc_server *server) {
Craig Tilleree945e82015-05-26 16:15:34 -0700493 listener *l;
494 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700495 for (l = server->listeners; l; l = l->next) {
496 n++;
497 }
Craig Tilleree945e82015-05-26 16:15:34 -0700498 return n;
499}
500
Craig Tillera82950e2015-09-22 12:33:20 -0700501static void done_shutdown_event(grpc_exec_ctx *exec_ctx, void *server,
502 grpc_cq_completion *completion) {
503 server_unref(exec_ctx, server);
Craig Tiller97fc6a32015-07-08 15:31:35 -0700504}
505
Craig Tillera82950e2015-09-22 12:33:20 -0700506static int num_channels(grpc_server *server) {
Craig Tillerab54f792015-07-08 08:34:20 -0700507 channel_data *chand;
508 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700509 for (chand = server->root_channel_data.next;
510 chand != &server->root_channel_data; chand = chand->next) {
511 n++;
512 }
Craig Tillerab54f792015-07-08 08:34:20 -0700513 return n;
514}
515
Craig Tillera82950e2015-09-22 12:33:20 -0700516static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx,
517 grpc_server *server) {
Craig Tiller1191e212015-07-30 14:49:02 -0700518 registered_method *rm;
Craig Tillera82950e2015-09-22 12:33:20 -0700519 request_matcher_kill_requests(exec_ctx, server,
520 &server->unregistered_request_matcher);
521 request_matcher_zombify_all_pending_calls(
522 exec_ctx, &server->unregistered_request_matcher);
523 for (rm = server->registered_methods; rm; rm = rm->next) {
524 request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher);
525 request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
526 }
Craig Tillerdc627722015-05-26 15:27:02 -0700527}
528
Craig Tillera82950e2015-09-22 12:33:20 -0700529static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
530 grpc_server *server) {
Craig Tiller45724b32015-09-22 10:42:19 -0700531 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700532 if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) {
533 return;
534 }
Craig Tiller45724b32015-09-22 10:42:19 -0700535
Craig Tillera82950e2015-09-22 12:33:20 -0700536 kill_pending_work_locked(exec_ctx, server);
Craig Tiller45724b32015-09-22 10:42:19 -0700537
Craig Tillera82950e2015-09-22 12:33:20 -0700538 if (server->root_channel_data.next != &server->root_channel_data ||
539 server->listeners_destroyed < num_listeners(server)) {
540 if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
541 server->last_shutdown_message_time),
542 gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
543 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
544 gpr_log(GPR_DEBUG,
545 "Waiting for %d channels and %d/%d listeners to be destroyed"
546 " before shutting down server",
547 num_channels(server),
548 num_listeners(server) - server->listeners_destroyed,
549 num_listeners(server));
Craig Tiller45724b32015-09-22 10:42:19 -0700550 }
Craig Tillera82950e2015-09-22 12:33:20 -0700551 return;
552 }
Craig Tiller45724b32015-09-22 10:42:19 -0700553 server->shutdown_published = 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700554 for (i = 0; i < server->num_shutdown_tags; i++) {
555 server_ref(server);
556 grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq,
557 server->shutdown_tags[i].tag, 1, done_shutdown_event, server,
558 &server->shutdown_tags[i].completion);
559 }
Craig Tiller45724b32015-09-22 10:42:19 -0700560}
561
Craig Tillera82950e2015-09-22 12:33:20 -0700562static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
Craig Tiller6902ad22015-04-16 08:01:49 -0700563 grpc_call_element *elem = user_data;
Craig Tillercce17ac2015-01-20 09:29:28 -0800564 call_data *calld = elem->call_data;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800565 if (md->key == GRPC_MDSTR_PATH) {
Craig Tillera82950e2015-09-22 12:33:20 -0700566 calld->path = GRPC_MDSTR_REF(md->value);
567 return NULL;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800568 } else if (md->key == GRPC_MDSTR_AUTHORITY) {
Craig Tillera82950e2015-09-22 12:33:20 -0700569 calld->host = GRPC_MDSTR_REF(md->value);
570 return NULL;
571 }
Craig Tiller6902ad22015-04-16 08:01:49 -0700572 return md;
573}
574
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800575static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
Craig Tiller6c396862016-01-28 13:53:40 -0800576 bool success) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700577 grpc_call_element *elem = ptr;
Craig Tiller6902ad22015-04-16 08:01:49 -0700578 call_data *calld = elem->call_data;
Craig Tiller94329d02015-07-23 09:52:11 -0700579 gpr_timespec op_deadline;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700580
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800581 grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
582 op_deadline = calld->recv_initial_metadata->deadline;
583 if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
584 calld->deadline = op_deadline;
585 }
586 if (calld->host && calld->path) {
587 /* do nothing */
588 } else {
589 success = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700590 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700591
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800592 calld->on_done_recv_initial_metadata->cb(
593 exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success);
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700594}
595
Craig Tillera82950e2015-09-22 12:33:20 -0700596static void server_mutate_op(grpc_call_element *elem,
597 grpc_transport_stream_op *op) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700598 call_data *calld = elem->call_data;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700599
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800600 if (op->recv_initial_metadata != NULL) {
601 calld->recv_initial_metadata = op->recv_initial_metadata;
Craig Tillera44cbfc2016-02-03 16:02:49 -0800602 calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
603 op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -0700604 }
Craig Tiller50d9db52015-04-23 10:52:14 -0700605}
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700606
Craig Tillera82950e2015-09-22 12:33:20 -0700607static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
608 grpc_call_element *elem,
609 grpc_transport_stream_op *op) {
610 GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
611 server_mutate_op(elem, op);
612 grpc_call_next_op(exec_ctx, elem, op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800613}
614
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800615static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
Craig Tiller6c396862016-01-28 13:53:40 -0800616 bool success) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800617 grpc_call_element *elem = ptr;
618 call_data *calld = elem->call_data;
619 if (success) {
620 start_new_rpc(exec_ctx, elem);
621 } else {
622 gpr_mu_lock(&calld->mu_state);
623 if (calld->state == NOT_STARTED) {
624 calld->state = ZOMBIED;
625 gpr_mu_unlock(&calld->mu_state);
626 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller6c396862016-01-28 13:53:40 -0800627 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800628 } else if (calld->state == PENDING) {
629 calld->state = ZOMBIED;
630 gpr_mu_unlock(&calld->mu_state);
631 /* zombied call will be destroyed when it's removed from the pending
632 queue... later */
633 } else {
634 gpr_mu_unlock(&calld->mu_state);
635 }
636 }
637}
638
639static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
640 grpc_transport *transport,
Craig Tillera82950e2015-09-22 12:33:20 -0700641 const void *transport_server_data) {
Craig Tillere039f032015-06-25 12:54:23 -0700642 channel_data *chand = cd;
643 /* create a call */
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800644 grpc_call *call =
645 grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data,
646 NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
647 grpc_call_element *elem =
648 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
649 call_data *calld = elem->call_data;
650 grpc_op op;
651 memset(&op, 0, sizeof(op));
652 op.op = GRPC_OP_RECV_INITIAL_METADATA;
653 op.data.recv_initial_metadata = &calld->initial_metadata;
654 grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem);
655 grpc_call_start_batch_and_execute(exec_ctx, call, &op, 1,
656 &calld->got_initial_metadata);
Craig Tillere039f032015-06-25 12:54:23 -0700657}
658
Craig Tillera82950e2015-09-22 12:33:20 -0700659static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd,
Craig Tiller6c396862016-01-28 13:53:40 -0800660 bool iomgr_status_ignored) {
Craig Tillere039f032015-06-25 12:54:23 -0700661 channel_data *chand = cd;
662 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700663 if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
664 grpc_transport_op op;
665 memset(&op, 0, sizeof(op));
666 op.on_connectivity_state_change = &chand->channel_connectivity_changed,
667 op.connectivity_state = &chand->connectivity_state;
668 grpc_channel_next_op(exec_ctx,
669 grpc_channel_stack_element(
670 grpc_channel_get_channel_stack(chand->channel), 0),
671 &op);
672 } else {
673 gpr_mu_lock(&server->mu_global);
674 destroy_channel(exec_ctx, chand);
675 gpr_mu_unlock(&server->mu_global);
676 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity");
677 }
Craig Tillere039f032015-06-25 12:54:23 -0700678}
679
Craig Tillera82950e2015-09-22 12:33:20 -0700680static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800681 grpc_call_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800682 call_data *calld = elem->call_data;
683 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700684 memset(calld, 0, sizeof(call_data));
685 calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
686 calld->call = grpc_call_from_top_element(elem);
687 gpr_mu_init(&calld->mu_state);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800688
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800689 grpc_closure_init(&calld->server_on_recv_initial_metadata,
690 server_on_recv_initial_metadata, elem);
Craig Tiller1e6facb2015-06-11 22:47:11 -0700691
Craig Tillera82950e2015-09-22 12:33:20 -0700692 server_ref(chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800693}
694
Craig Tillera82950e2015-09-22 12:33:20 -0700695static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
696 grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800697 channel_data *chand = elem->channel_data;
Craig Tillerdb7db992015-01-29 11:19:01 -0800698 call_data *calld = elem->call_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800699
Craig Tillera82950e2015-09-22 12:33:20 -0700700 GPR_ASSERT(calld->state != PENDING);
Craig Tiller092d8d12015-07-04 22:35:00 -0700701
Craig Tillera82950e2015-09-22 12:33:20 -0700702 if (calld->host) {
703 GRPC_MDSTR_UNREF(calld->host);
704 }
705 if (calld->path) {
706 GRPC_MDSTR_UNREF(calld->path);
707 }
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800708 grpc_metadata_array_destroy(&calld->initial_metadata);
Craig Tiller4df31a62015-01-30 09:44:31 -0800709
Craig Tillera82950e2015-09-22 12:33:20 -0700710 gpr_mu_destroy(&calld->mu_state);
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700711
Craig Tillera82950e2015-09-22 12:33:20 -0700712 server_unref(exec_ctx, chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800713}
714
Craig Tillera82950e2015-09-22 12:33:20 -0700715static void init_channel_elem(grpc_exec_ctx *exec_ctx,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800716 grpc_channel_element *elem,
717 grpc_channel_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800718 channel_data *chand = elem->channel_data;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800719 GPR_ASSERT(args->is_first);
720 GPR_ASSERT(!args->is_last);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800721 chand->server = NULL;
722 chand->channel = NULL;
723 chand->next = chand->prev = chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800724 chand->registered_methods = NULL;
Craig Tillere039f032015-06-25 12:54:23 -0700725 chand->connectivity_state = GRPC_CHANNEL_IDLE;
Craig Tillera82950e2015-09-22 12:33:20 -0700726 grpc_closure_init(&chand->channel_connectivity_changed,
727 channel_connectivity_changed, chand);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800728}
729
Craig Tillera82950e2015-09-22 12:33:20 -0700730static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
731 grpc_channel_element *elem) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800732 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800733 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700734 if (chand->registered_methods) {
735 for (i = 0; i < chand->registered_method_slots; i++) {
736 if (chand->registered_methods[i].method) {
737 GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
738 }
739 if (chand->registered_methods[i].host) {
740 GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
741 }
Craig Tillerec3257c2015-02-12 15:59:43 -0800742 }
Craig Tillera82950e2015-09-22 12:33:20 -0700743 gpr_free(chand->registered_methods);
744 }
745 if (chand->server) {
746 gpr_mu_lock(&chand->server->mu_global);
747 chand->next->prev = chand->prev;
748 chand->prev->next = chand->next;
749 chand->next = chand->prev = chand;
750 maybe_finish_shutdown(exec_ctx, chand->server);
751 gpr_mu_unlock(&chand->server->mu_global);
Craig Tillera82950e2015-09-22 12:33:20 -0700752 server_unref(exec_ctx, chand->server);
753 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800754}
755
Craig Tiller178edfa2016-02-17 20:54:46 -0800756const grpc_channel_filter grpc_server_top_filter = {
Craig Tillerf40df232016-03-25 13:38:14 -0700757 server_start_transport_stream_op,
758 grpc_channel_next_op,
759 sizeof(call_data),
760 init_call_elem,
761 grpc_call_stack_ignore_set_pollset,
762 destroy_call_elem,
763 sizeof(channel_data),
764 init_channel_elem,
765 destroy_channel_elem,
766 grpc_call_next_get_peer,
767 "server",
Craig Tiller9f28ac22015-01-27 17:01:29 -0800768};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800769
Craig Tillera82950e2015-09-22 12:33:20 -0700770void grpc_server_register_completion_queue(grpc_server *server,
771 grpc_completion_queue *cq,
772 void *reserved) {
Craig Tiller20bc56d2015-02-12 09:02:56 -0800773 size_t i, n;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700774 GRPC_API_TRACE(
775 "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
776 (server, cq, reserved));
Craig Tillera82950e2015-09-22 12:33:20 -0700777 GPR_ASSERT(!reserved);
778 for (i = 0; i < server->cq_count; i++) {
779 if (server->cqs[i] == cq) return;
780 }
781 GRPC_CQ_INTERNAL_REF(cq, "server");
782 grpc_cq_mark_server_cq(cq);
Craig Tiller20bc56d2015-02-12 09:02:56 -0800783 n = server->cq_count++;
Craig Tillera82950e2015-09-22 12:33:20 -0700784 server->cqs = gpr_realloc(server->cqs,
785 server->cq_count * sizeof(grpc_completion_queue *));
Craig Tiller20bc56d2015-02-12 09:02:56 -0800786 server->cqs[n] = cq;
787}
788
Craig Tiller178edfa2016-02-17 20:54:46 -0800789grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800790 size_t i;
Craig Tiller178edfa2016-02-17 20:54:46 -0800791
792 GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800793
Craig Tillera82950e2015-09-22 12:33:20 -0700794 grpc_server *server = gpr_malloc(sizeof(grpc_server));
Craig Tiller60fd3612015-03-05 16:24:22 -0800795
Craig Tillera82950e2015-09-22 12:33:20 -0700796 GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
Craig Tiller60fd3612015-03-05 16:24:22 -0800797
Craig Tillera82950e2015-09-22 12:33:20 -0700798 memset(server, 0, sizeof(grpc_server));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800799
Craig Tillera82950e2015-09-22 12:33:20 -0700800 gpr_mu_init(&server->mu_global);
801 gpr_mu_init(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800802
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800803 /* decremented by grpc_server_destroy */
Craig Tillera82950e2015-09-22 12:33:20 -0700804 gpr_ref_init(&server->internal_refcount, 1);
805 server->root_channel_data.next = server->root_channel_data.prev =
806 &server->root_channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800807
Craig Tiller6a006ce2015-07-13 16:25:40 -0700808 /* TODO(ctiller): expose a channel_arg for this */
809 server->max_requested_calls = 32768;
Craig Tillera82950e2015-09-22 12:33:20 -0700810 server->request_freelist =
811 gpr_stack_lockfree_create(server->max_requested_calls);
812 for (i = 0; i < (size_t)server->max_requested_calls; i++) {
813 gpr_stack_lockfree_push(server->request_freelist, (int)i);
814 }
815 request_matcher_init(&server->unregistered_request_matcher,
816 server->max_requested_calls);
817 server->requested_calls = gpr_malloc(server->max_requested_calls *
818 sizeof(*server->requested_calls));
Craig Tiller729b35a2015-07-13 12:36:47 -0700819
Craig Tillera82950e2015-09-22 12:33:20 -0700820 server->channel_args = grpc_channel_args_copy(args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800821
822 return server;
823}
824
Craig Tillera82950e2015-09-22 12:33:20 -0700825static int streq(const char *a, const char *b) {
826 if (a == NULL && b == NULL) return 1;
827 if (a == NULL) return 0;
828 if (b == NULL) return 0;
829 return 0 == strcmp(a, b);
Craig Tiller24be0f72015-02-10 14:04:22 -0800830}
831
Craig Tillera82950e2015-09-22 12:33:20 -0700832void *grpc_server_register_method(grpc_server *server, const char *method,
833 const char *host) {
Craig Tiller24be0f72015-02-10 14:04:22 -0800834 registered_method *m;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700835 GRPC_API_TRACE("grpc_server_register_method(server=%p, method=%s, host=%s)",
836 3, (server, method, host));
Craig Tillera82950e2015-09-22 12:33:20 -0700837 if (!method) {
838 gpr_log(GPR_ERROR,
839 "grpc_server_register_method method string cannot be NULL");
840 return NULL;
841 }
842 for (m = server->registered_methods; m; m = m->next) {
843 if (streq(m->method, method) && streq(m->host, host)) {
844 gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
845 host ? host : "*");
Craig Tiller24be0f72015-02-10 14:04:22 -0800846 return NULL;
847 }
Craig Tillera82950e2015-09-22 12:33:20 -0700848 }
849 m = gpr_malloc(sizeof(registered_method));
850 memset(m, 0, sizeof(*m));
851 request_matcher_init(&m->request_matcher, server->max_requested_calls);
852 m->method = gpr_strdup(method);
853 m->host = gpr_strdup(host);
Craig Tiller24be0f72015-02-10 14:04:22 -0800854 m->next = server->registered_methods;
855 server->registered_methods = m;
856 return m;
857}
858
Craig Tillera82950e2015-09-22 12:33:20 -0700859void grpc_server_start(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800860 listener *l;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800861 size_t i;
Craig Tillerf5768a62015-09-22 10:54:34 -0700862 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800863
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700864 GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
865
Craig Tillera82950e2015-09-22 12:33:20 -0700866 server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
867 for (i = 0; i < server->cq_count; i++) {
868 server->pollsets[i] = grpc_cq_pollset(server->cqs[i]);
869 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800870
Craig Tillera82950e2015-09-22 12:33:20 -0700871 for (l = server->listeners; l; l = l->next) {
872 l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count);
873 }
Craig Tillerdfff1b82015-09-21 14:39:57 -0700874
Craig Tillera82950e2015-09-22 12:33:20 -0700875 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800876}
877
Craig Tillera82950e2015-09-22 12:33:20 -0700878void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
879 grpc_transport *transport,
Craig Tillera82950e2015-09-22 12:33:20 -0700880 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800881 size_t i;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800882 size_t num_registered_methods;
883 size_t alloc;
884 registered_method *rm;
885 channel_registered_method *crm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800886 grpc_channel *channel;
887 channel_data *chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800888 grpc_mdstr *host;
889 grpc_mdstr *method;
Craig Tiller7536af02015-12-22 13:49:30 -0800890 uint32_t hash;
Craig Tillerf96dfc32015-09-10 14:43:18 -0700891 size_t slots;
Craig Tiller7536af02015-12-22 13:49:30 -0800892 uint32_t probes;
893 uint32_t max_probes = 0;
Craig Tillere039f032015-06-25 12:54:23 -0700894 grpc_transport_op op;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800895
Craig Tillera82950e2015-09-22 12:33:20 -0700896 for (i = 0; i < s->cq_count; i++) {
897 memset(&op, 0, sizeof(op));
898 op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
899 grpc_transport_perform_op(exec_ctx, transport, &op);
900 }
ctillerd79b4862014-12-17 16:36:59 -0800901
Craig Tiller178edfa2016-02-17 20:54:46 -0800902 channel =
903 grpc_channel_create(exec_ctx, NULL, args, GRPC_SERVER_CHANNEL, transport);
Craig Tillera82950e2015-09-22 12:33:20 -0700904 chand = (channel_data *)grpc_channel_stack_element(
Craig Tillerf40df232016-03-25 13:38:14 -0700905 grpc_channel_get_channel_stack(channel), 0)
906 ->channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800907 chand->server = s;
Craig Tillera82950e2015-09-22 12:33:20 -0700908 server_ref(s);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800909 chand->channel = channel;
910
Craig Tiller04cc8be2015-02-10 16:11:22 -0800911 num_registered_methods = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700912 for (rm = s->registered_methods; rm; rm = rm->next) {
913 num_registered_methods++;
914 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800915 /* build a lookup table phrased in terms of mdstr's in this channels context
916 to quickly find registered methods */
Craig Tillera82950e2015-09-22 12:33:20 -0700917 if (num_registered_methods > 0) {
918 slots = 2 * num_registered_methods;
919 alloc = sizeof(channel_registered_method) * slots;
920 chand->registered_methods = gpr_malloc(alloc);
921 memset(chand->registered_methods, 0, alloc);
922 for (rm = s->registered_methods; rm; rm = rm->next) {
Craig Tillerb2b42612015-11-20 12:02:17 -0800923 host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL;
924 method = grpc_mdstr_from_string(rm->method);
Craig Tillera82950e2015-09-22 12:33:20 -0700925 hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
926 for (probes = 0; chand->registered_methods[(hash + probes) % slots]
Craig Tillerf40df232016-03-25 13:38:14 -0700927 .server_registered_method != NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700928 probes++)
929 ;
930 if (probes > max_probes) max_probes = probes;
931 crm = &chand->registered_methods[(hash + probes) % slots];
932 crm->server_registered_method = rm;
933 crm->host = host;
934 crm->method = method;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800935 }
Craig Tiller7536af02015-12-22 13:49:30 -0800936 GPR_ASSERT(slots <= UINT32_MAX);
937 chand->registered_method_slots = (uint32_t)slots;
Craig Tillera82950e2015-09-22 12:33:20 -0700938 chand->registered_method_max_probes = max_probes;
939 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800940
Craig Tillera82950e2015-09-22 12:33:20 -0700941 gpr_mu_lock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800942 chand->next = &s->root_channel_data;
943 chand->prev = chand->next->prev;
944 chand->next->prev = chand->prev->next = chand;
Craig Tillera82950e2015-09-22 12:33:20 -0700945 gpr_mu_unlock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800946
Craig Tillera82950e2015-09-22 12:33:20 -0700947 GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity");
948 memset(&op, 0, sizeof(op));
Craig Tillerd7f12e32016-03-03 10:08:31 -0800949 op.set_accept_stream = true;
950 op.set_accept_stream_fn = accept_stream;
Craig Tiller4b804102015-06-26 16:16:12 -0700951 op.set_accept_stream_user_data = chand;
952 op.on_connectivity_state_change = &chand->channel_connectivity_changed;
953 op.connectivity_state = &chand->connectivity_state;
Craig Tillera82950e2015-09-22 12:33:20 -0700954 op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0;
955 grpc_transport_perform_op(exec_ctx, transport, &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800956}
957
Craig Tillera82950e2015-09-22 12:33:20 -0700958void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg,
959 grpc_cq_completion *storage) {
960 (void)done_arg;
961 gpr_free(storage);
murgatroid9900a3dab2015-08-19 11:15:38 -0700962}
963
Craig Tillera82950e2015-09-22 12:33:20 -0700964static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s,
Craig Tiller6c396862016-01-28 13:53:40 -0800965 bool success) {
Craig Tillerdfff1b82015-09-21 14:39:57 -0700966 grpc_server *server = s;
Craig Tillera82950e2015-09-22 12:33:20 -0700967 gpr_mu_lock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700968 server->listeners_destroyed++;
Craig Tillera82950e2015-09-22 12:33:20 -0700969 maybe_finish_shutdown(exec_ctx, server);
970 gpr_mu_unlock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700971}
972
Craig Tillera82950e2015-09-22 12:33:20 -0700973void grpc_server_shutdown_and_notify(grpc_server *server,
974 grpc_completion_queue *cq, void *tag) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800975 listener *l;
Craig Tillerbce999f2015-05-27 09:55:51 -0700976 shutdown_tag *sdt;
Craig Tillerff3ae682015-06-29 17:44:04 -0700977 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -0700978 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800979
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700980 GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3,
981 (server, cq, tag));
982
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800983 /* lock, and gather up some stuff to do */
Craig Tillera82950e2015-09-22 12:33:20 -0700984 gpr_mu_lock(&server->mu_global);
Craig Tiller4bf29282015-12-14 11:25:48 -0800985 grpc_cq_begin_op(cq, tag);
Craig Tillera82950e2015-09-22 12:33:20 -0700986 if (server->shutdown_published) {
987 grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL,
988 gpr_malloc(sizeof(grpc_cq_completion)));
989 gpr_mu_unlock(&server->mu_global);
990 goto done;
991 }
992 server->shutdown_tags =
993 gpr_realloc(server->shutdown_tags,
994 sizeof(shutdown_tag) * (server->num_shutdown_tags + 1));
Craig Tillerbce999f2015-05-27 09:55:51 -0700995 sdt = &server->shutdown_tags[server->num_shutdown_tags++];
996 sdt->tag = tag;
997 sdt->cq = cq;
Craig Tillera82950e2015-09-22 12:33:20 -0700998 if (gpr_atm_acq_load(&server->shutdown_flag)) {
999 gpr_mu_unlock(&server->mu_global);
1000 goto done;
1001 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001002
Craig Tillera82950e2015-09-22 12:33:20 -07001003 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
Craig Tillerab54f792015-07-08 08:34:20 -07001004
Craig Tillera82950e2015-09-22 12:33:20 -07001005 channel_broadcaster_init(server, &broadcaster);
nnoble0c475f02014-12-05 15:37:39 -08001006
Craig Tillerfc193e12015-09-24 15:29:03 -07001007 gpr_atm_rel_store(&server->shutdown_flag, 1);
1008
Craig Tillerbd217572015-02-11 18:10:56 -08001009 /* collect all unregistered then registered calls */
Craig Tillera82950e2015-09-22 12:33:20 -07001010 gpr_mu_lock(&server->mu_call);
1011 kill_pending_work_locked(&exec_ctx, server);
1012 gpr_mu_unlock(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001013
Craig Tillera82950e2015-09-22 12:33:20 -07001014 maybe_finish_shutdown(&exec_ctx, server);
1015 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001016
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001017 /* Shutdown listeners */
Craig Tillera82950e2015-09-22 12:33:20 -07001018 for (l = server->listeners; l; l = l->next) {
1019 grpc_closure_init(&l->destroy_done, listener_destroy_done, server);
1020 l->destroy(&exec_ctx, server, l->arg, &l->destroy_done);
1021 }
Craig Tillerff3ae682015-06-29 17:44:04 -07001022
Craig Tillera82950e2015-09-22 12:33:20 -07001023 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001024
Craig Tillerdfff1b82015-09-21 14:39:57 -07001025done:
Craig Tillera82950e2015-09-22 12:33:20 -07001026 grpc_exec_ctx_finish(&exec_ctx);
Craig Tilleraec96aa2015-04-07 14:32:15 -07001027}
1028
Craig Tillera82950e2015-09-22 12:33:20 -07001029void grpc_server_cancel_all_calls(grpc_server *server) {
Craig Tiller092d8d12015-07-04 22:35:00 -07001030 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001031 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillerafa2d632015-05-26 16:39:13 -07001032
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001033 GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server));
1034
Craig Tillera82950e2015-09-22 12:33:20 -07001035 gpr_mu_lock(&server->mu_global);
1036 channel_broadcaster_init(server, &broadcaster);
1037 gpr_mu_unlock(&server->mu_global);
Craig Tillerafa2d632015-05-26 16:39:13 -07001038
Craig Tillera82950e2015-09-22 12:33:20 -07001039 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1);
1040 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerafa2d632015-05-26 16:39:13 -07001041}
1042
Craig Tillera82950e2015-09-22 12:33:20 -07001043void grpc_server_destroy(grpc_server *server) {
Craig Tilleraec96aa2015-04-07 14:32:15 -07001044 listener *l;
Craig Tillerf5768a62015-09-22 10:54:34 -07001045 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller872af022015-04-24 15:57:52 -07001046
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001047 GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server));
1048
Craig Tillera82950e2015-09-22 12:33:20 -07001049 gpr_mu_lock(&server->mu_global);
1050 GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners);
1051 GPR_ASSERT(server->listeners_destroyed == num_listeners(server));
Craig Tilleraec96aa2015-04-07 14:32:15 -07001052
Craig Tillera82950e2015-09-22 12:33:20 -07001053 while (server->listeners) {
1054 l = server->listeners;
1055 server->listeners = l->next;
1056 gpr_free(l);
1057 }
Craig Tilleraec96aa2015-04-07 14:32:15 -07001058
Craig Tillera82950e2015-09-22 12:33:20 -07001059 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001060
Craig Tillera82950e2015-09-22 12:33:20 -07001061 server_unref(&exec_ctx, server);
1062 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001063}
1064
Craig Tillera82950e2015-09-22 12:33:20 -07001065void grpc_server_add_listener(
1066 grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1067 void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1068 grpc_pollset **pollsets, size_t pollset_count),
1069 void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1070 grpc_closure *on_done)) {
1071 listener *l = gpr_malloc(sizeof(listener));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001072 l->arg = arg;
1073 l->start = start;
1074 l->destroy = destroy;
1075 l->next = server->listeners;
1076 server->listeners = l;
1077}
1078
Craig Tillera82950e2015-09-22 12:33:20 -07001079static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1080 grpc_server *server,
1081 requested_call *rc) {
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001082 call_data *calld = NULL;
Craig Tillerb9d35962015-09-11 13:31:16 -07001083 request_matcher *rm = NULL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001084 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -07001085 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1086 fail_call(exec_ctx, server, rc);
1087 return GRPC_CALL_OK;
1088 }
1089 request_id = gpr_stack_lockfree_pop(server->request_freelist);
1090 if (request_id == -1) {
1091 /* out of request ids: just fail this one */
1092 fail_call(exec_ctx, server, rc);
1093 return GRPC_CALL_OK;
1094 }
1095 switch (rc->type) {
Craig Tiller04cc8be2015-02-10 16:11:22 -08001096 case BATCH_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001097 rm = &server->unregistered_request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001098 break;
1099 case REGISTERED_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001100 rm = &rc->data.registered.registered_method->request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001101 break;
Craig Tillera82950e2015-09-22 12:33:20 -07001102 }
Craig Tiller45724b32015-09-22 10:42:19 -07001103 server->requested_calls[request_id] = *rc;
Craig Tillera82950e2015-09-22 12:33:20 -07001104 gpr_free(rc);
Craig Tillerb9d35962015-09-11 13:31:16 -07001105 if (gpr_stack_lockfree_push(rm->requests, request_id)) {
Craig Tillera82950e2015-09-22 12:33:20 -07001106 /* this was the first queued request: we need to lock and start
1107 matching calls */
1108 gpr_mu_lock(&server->mu_call);
Craig Tillerb9d35962015-09-11 13:31:16 -07001109 while ((calld = rm->pending_head) != NULL) {
1110 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -07001111 if (request_id == -1) break;
Craig Tillerb9d35962015-09-11 13:31:16 -07001112 rm->pending_head = calld->pending_next;
Craig Tillera82950e2015-09-22 12:33:20 -07001113 gpr_mu_unlock(&server->mu_call);
1114 gpr_mu_lock(&calld->mu_state);
1115 if (calld->state == ZOMBIED) {
1116 gpr_mu_unlock(&calld->mu_state);
1117 grpc_closure_init(
1118 &calld->kill_zombie_closure, kill_zombie,
1119 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
Craig Tiller6c396862016-01-28 13:53:40 -08001120 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true,
1121 NULL);
Craig Tillera82950e2015-09-22 12:33:20 -07001122 } else {
1123 GPR_ASSERT(calld->state == PENDING);
1124 calld->state = ACTIVATED;
1125 gpr_mu_unlock(&calld->mu_state);
1126 begin_call(exec_ctx, server, calld,
1127 &server->requested_calls[request_id]);
1128 }
1129 gpr_mu_lock(&server->mu_call);
Craig Tiller45724b32015-09-22 10:42:19 -07001130 }
Craig Tillera82950e2015-09-22 12:33:20 -07001131 gpr_mu_unlock(&server->mu_call);
1132 }
Craig Tiller6a006ce2015-07-13 16:25:40 -07001133 return GRPC_CALL_OK;
Craig Tillercce17ac2015-01-20 09:29:28 -08001134}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001135
Craig Tillera82950e2015-09-22 12:33:20 -07001136grpc_call_error grpc_server_request_call(
1137 grpc_server *server, grpc_call **call, grpc_call_details *details,
1138 grpc_metadata_array *initial_metadata,
1139 grpc_completion_queue *cq_bound_to_call,
1140 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001141 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001142 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001143 requested_call *rc = gpr_malloc(sizeof(*rc));
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001144 GRPC_API_TRACE(
1145 "grpc_server_request_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001146 "server=%p, call=%p, details=%p, initial_metadata=%p, "
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001147 "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001148 7, (server, call, details, initial_metadata, cq_bound_to_call,
1149 cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001150 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1151 gpr_free(rc);
1152 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1153 goto done;
1154 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001155 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller9928d392015-08-18 09:40:24 -07001156 details->reserved = NULL;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001157 rc->type = BATCH_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001158 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001159 rc->tag = tag;
1160 rc->cq_bound_to_call = cq_bound_to_call;
1161 rc->cq_for_notification = cq_for_notification;
1162 rc->call = call;
1163 rc->data.batch.details = details;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001164 rc->initial_metadata = initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -07001165 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001166done:
Craig Tillera82950e2015-09-22 12:33:20 -07001167 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001168 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001169}
1170
Craig Tillera82950e2015-09-22 12:33:20 -07001171grpc_call_error grpc_server_request_registered_call(
Craig Tillerb9d35962015-09-11 13:31:16 -07001172 grpc_server *server, void *rmp, grpc_call **call, gpr_timespec *deadline,
Craig Tillera82950e2015-09-22 12:33:20 -07001173 grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload,
1174 grpc_completion_queue *cq_bound_to_call,
1175 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001176 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001177 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001178 requested_call *rc = gpr_malloc(sizeof(*rc));
Craig Tillerb9d35962015-09-11 13:31:16 -07001179 registered_method *rm = rmp;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001180 GRPC_API_TRACE(
1181 "grpc_server_request_registered_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001182 "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, "
1183 "optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
1184 "tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001185 9, (server, rmp, call, deadline, initial_metadata, optional_payload,
1186 cq_bound_to_call, cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001187 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1188 gpr_free(rc);
1189 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1190 goto done;
1191 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001192 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001193 rc->type = REGISTERED_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001194 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001195 rc->tag = tag;
1196 rc->cq_bound_to_call = cq_bound_to_call;
1197 rc->cq_for_notification = cq_for_notification;
1198 rc->call = call;
Craig Tillerb9d35962015-09-11 13:31:16 -07001199 rc->data.registered.registered_method = rm;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001200 rc->data.registered.deadline = deadline;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001201 rc->initial_metadata = initial_metadata;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001202 rc->data.registered.optional_payload = optional_payload;
Craig Tillera82950e2015-09-22 12:33:20 -07001203 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001204done:
Craig Tillera82950e2015-09-22 12:33:20 -07001205 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001206 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001207}
1208
Craig Tillera82950e2015-09-22 12:33:20 -07001209static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx,
Craig Tiller6c396862016-01-28 13:53:40 -08001210 void *user_data, bool success);
Craig Tiller24be0f72015-02-10 14:04:22 -08001211
Craig Tillera82950e2015-09-22 12:33:20 -07001212static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
Craig Tiller166e2502015-02-03 20:14:41 -08001213 gpr_slice slice = value->slice;
Craig Tillera82950e2015-09-22 12:33:20 -07001214 size_t len = GPR_SLICE_LENGTH(slice);
Craig Tiller166e2502015-02-03 20:14:41 -08001215
Craig Tillera82950e2015-09-22 12:33:20 -07001216 if (len + 1 > *capacity) {
1217 *capacity = GPR_MAX(len + 1, *capacity * 2);
1218 *dest = gpr_realloc(*dest, *capacity);
1219 }
1220 memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
Craig Tiller166e2502015-02-03 20:14:41 -08001221}
1222
Craig Tillera82950e2015-09-22 12:33:20 -07001223static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1224 call_data *calld, requested_call *rc) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001225 grpc_op ops[1];
1226 grpc_op *op = ops;
1227
1228 memset(ops, 0, sizeof(ops));
Craig Tiller24be0f72015-02-10 14:04:22 -08001229
1230 /* called once initial metadata has been read by the call, but BEFORE
1231 the ioreq to fetch it out of the call has been executed.
1232 This means metadata related fields can be relied on in calld, but to
1233 fill in the metadata array passed by the client, we need to perform
1234 an ioreq op, that should complete immediately. */
1235
Craig Tillera82950e2015-09-22 12:33:20 -07001236 grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001237 grpc_closure_init(&rc->publish, publish_registered_or_batch, rc);
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001238 *rc->call = calld->call;
1239 calld->cq_new = rc->cq_for_notification;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001240 GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
Craig Tillera82950e2015-09-22 12:33:20 -07001241 switch (rc->type) {
Craig Tiller24be0f72015-02-10 14:04:22 -08001242 case BATCH_CALL:
Craig Tillera82950e2015-09-22 12:33:20 -07001243 GPR_ASSERT(calld->host != NULL);
1244 GPR_ASSERT(calld->path != NULL);
1245 cpstr(&rc->data.batch.details->host,
1246 &rc->data.batch.details->host_capacity, calld->host);
1247 cpstr(&rc->data.batch.details->method,
1248 &rc->data.batch.details->method_capacity, calld->path);
Masood Malekghassemibf177c82015-04-27 12:14:38 -07001249 rc->data.batch.details->deadline = calld->deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -08001250 break;
1251 case REGISTERED_CALL:
1252 *rc->data.registered.deadline = calld->deadline;
Craig Tillera82950e2015-09-22 12:33:20 -07001253 if (rc->data.registered.optional_payload) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001254 op->op = GRPC_OP_RECV_MESSAGE;
1255 op->data.recv_message = rc->data.registered.optional_payload;
1256 op++;
Craig Tillera82950e2015-09-22 12:33:20 -07001257 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001258 break;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001259 default:
1260 GPR_UNREACHABLE_CODE(return );
Craig Tillera82950e2015-09-22 12:33:20 -07001261 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001262
Craig Tillera82950e2015-09-22 12:33:20 -07001263 GRPC_CALL_INTERNAL_REF(calld->call, "server");
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001264 grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops,
1265 (size_t)(op - ops), &rc->publish);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001266}
1267
Craig Tillera82950e2015-09-22 12:33:20 -07001268static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
1269 grpc_cq_completion *c) {
Craig Tiller6a006ce2015-07-13 16:25:40 -07001270 requested_call *rc = req;
1271 grpc_server *server = rc->server;
1272
Craig Tillera82950e2015-09-22 12:33:20 -07001273 if (rc >= server->requested_calls &&
1274 rc < server->requested_calls + server->max_requested_calls) {
1275 GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
1276 gpr_stack_lockfree_push(server->request_freelist,
1277 (int)(rc - server->requested_calls));
1278 } else {
1279 gpr_free(req);
1280 }
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001281
Craig Tillera82950e2015-09-22 12:33:20 -07001282 server_unref(exec_ctx, server);
Craig Tiller24be0f72015-02-10 14:04:22 -08001283}
1284
Craig Tillera82950e2015-09-22 12:33:20 -07001285static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1286 requested_call *rc) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001287 *rc->call = NULL;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001288 rc->initial_metadata->count = 0;
1289
Craig Tillera82950e2015-09-22 12:33:20 -07001290 server_ref(server);
1291 grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
1292 done_request_event, rc, &rc->completion);
Craig Tiller24be0f72015-02-10 14:04:22 -08001293}
1294
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001295static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc,
Craig Tiller6c396862016-01-28 13:53:40 -08001296 bool success) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001297 requested_call *rc = prc;
1298 grpc_call *call = *rc->call;
Craig Tillera82950e2015-09-22 12:33:20 -07001299 grpc_call_element *elem =
1300 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
Craig Tiller20bc56d2015-02-12 09:02:56 -08001301 call_data *calld = elem->call_data;
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001302 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001303 server_ref(chand->server);
1304 grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event,
1305 rc, &rc->completion);
1306 GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server");
Craig Tiller24be0f72015-02-10 14:04:22 -08001307}
1308
Craig Tillera82950e2015-09-22 12:33:20 -07001309const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001310 return server->channel_args;
Craig Tiller190d3602015-02-18 09:23:38 -08001311}
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001312
Craig Tillera82950e2015-09-22 12:33:20 -07001313int grpc_server_has_open_connections(grpc_server *server) {
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001314 int r;
Craig Tillera82950e2015-09-22 12:33:20 -07001315 gpr_mu_lock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001316 r = server->root_channel_data.next != &server->root_channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001317 gpr_mu_unlock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001318 return r;
1319}