blob: c88f769eda9ca0a19f8452ea2af18372e701c47a [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Bogdan Drutuaff40662016-01-25 10:21:38 -08003 * Copyright 2015-2016, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include "src/core/surface/server.h"
35
Craig Tillerf96dfc32015-09-10 14:43:18 -070036#include <limits.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080037#include <stdlib.h>
38#include <string.h>
39
Craig Tiller6a006ce2015-07-13 16:25:40 -070040#include <grpc/support/alloc.h>
41#include <grpc/support/log.h>
42#include <grpc/support/string_util.h>
43#include <grpc/support/useful.h>
44
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080045#include "src/core/channel/channel_args.h"
46#include "src/core/channel/connected_channel.h"
ctiller18b49ab2014-12-09 14:39:16 -080047#include "src/core/iomgr/iomgr.h"
Craig Tiller6a006ce2015-07-13 16:25:40 -070048#include "src/core/support/stack_lockfree.h"
Craig Tiller485d7762015-01-23 12:54:05 -080049#include "src/core/support/string.h"
Masood Malekghassemi76c3d742015-08-19 18:22:53 -070050#include "src/core/surface/api_trace.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"
Craig Tillerebdef9d2015-11-19 17:09:49 -080056#include "src/core/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 Tiller6c396862016-01-28 13:53:40 -0800406 grpc_exec_ctx_enqueue(exec_ctx, &chand->finish_destroy_channel_closure, true,
407 NULL);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800408}
409
Craig Tillera82950e2015-09-22 12:33:20 -0700410static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server,
Craig Tiller8dc09712015-09-24 13:58:16 -0700411 grpc_call_element *elem, request_matcher *rm) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800412 call_data *calld = elem->call_data;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700413 int request_id;
414
Craig Tillera82950e2015-09-22 12:33:20 -0700415 if (gpr_atm_acq_load(&server->shutdown_flag)) {
416 gpr_mu_lock(&calld->mu_state);
417 calld->state = ZOMBIED;
418 gpr_mu_unlock(&calld->mu_state);
419 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller6c396862016-01-28 13:53:40 -0800420 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillera82950e2015-09-22 12:33:20 -0700421 return;
422 }
Craig Tiller45724b32015-09-22 10:42:19 -0700423
Craig Tillerb9d35962015-09-11 13:31:16 -0700424 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -0700425 if (request_id == -1) {
426 gpr_mu_lock(&server->mu_call);
427 gpr_mu_lock(&calld->mu_state);
428 calld->state = PENDING;
429 gpr_mu_unlock(&calld->mu_state);
Craig Tillerb9d35962015-09-11 13:31:16 -0700430 if (rm->pending_head == NULL) {
431 rm->pending_tail = rm->pending_head = calld;
Craig Tillera82950e2015-09-22 12:33:20 -0700432 } else {
Craig Tillerb9d35962015-09-11 13:31:16 -0700433 rm->pending_tail->pending_next = calld;
434 rm->pending_tail = calld;
Craig Tiller45724b32015-09-22 10:42:19 -0700435 }
Craig Tillera82950e2015-09-22 12:33:20 -0700436 calld->pending_next = NULL;
437 gpr_mu_unlock(&server->mu_call);
438 } else {
439 gpr_mu_lock(&calld->mu_state);
440 calld->state = ACTIVATED;
441 gpr_mu_unlock(&calld->mu_state);
442 begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
443 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800444}
445
Craig Tillera82950e2015-09-22 12:33:20 -0700446static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800447 channel_data *chand = elem->channel_data;
448 call_data *calld = elem->call_data;
449 grpc_server *server = chand->server;
Craig Tiller7536af02015-12-22 13:49:30 -0800450 uint32_t i;
451 uint32_t hash;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800452 channel_registered_method *rm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800453
Craig Tillera82950e2015-09-22 12:33:20 -0700454 if (chand->registered_methods && calld->path && calld->host) {
455 /* TODO(ctiller): unify these two searches */
456 /* check for an exact match with host */
457 hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
458 for (i = 0; i <= chand->registered_method_max_probes; i++) {
459 rm = &chand->registered_methods[(hash + i) %
460 chand->registered_method_slots];
461 if (!rm) break;
462 if (rm->host != calld->host) continue;
463 if (rm->method != calld->path) continue;
464 finish_start_new_rpc(exec_ctx, server, elem,
465 &rm->server_registered_method->request_matcher);
466 return;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800467 }
Craig Tillera82950e2015-09-22 12:33:20 -0700468 /* check for a wildcard method definition (no host set) */
469 hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
470 for (i = 0; i <= chand->registered_method_max_probes; i++) {
471 rm = &chand->registered_methods[(hash + i) %
472 chand->registered_method_slots];
473 if (!rm) break;
474 if (rm->host != NULL) continue;
475 if (rm->method != calld->path) continue;
476 finish_start_new_rpc(exec_ctx, server, elem,
477 &rm->server_registered_method->request_matcher);
478 return;
479 }
480 }
481 finish_start_new_rpc(exec_ctx, server, elem,
482 &server->unregistered_request_matcher);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800483}
484
Craig Tillera82950e2015-09-22 12:33:20 -0700485static int num_listeners(grpc_server *server) {
Craig Tilleree945e82015-05-26 16:15:34 -0700486 listener *l;
487 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700488 for (l = server->listeners; l; l = l->next) {
489 n++;
490 }
Craig Tilleree945e82015-05-26 16:15:34 -0700491 return n;
492}
493
Craig Tillera82950e2015-09-22 12:33:20 -0700494static void done_shutdown_event(grpc_exec_ctx *exec_ctx, void *server,
495 grpc_cq_completion *completion) {
496 server_unref(exec_ctx, server);
Craig Tiller97fc6a32015-07-08 15:31:35 -0700497}
498
Craig Tillera82950e2015-09-22 12:33:20 -0700499static int num_channels(grpc_server *server) {
Craig Tillerab54f792015-07-08 08:34:20 -0700500 channel_data *chand;
501 int n = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700502 for (chand = server->root_channel_data.next;
503 chand != &server->root_channel_data; chand = chand->next) {
504 n++;
505 }
Craig Tillerab54f792015-07-08 08:34:20 -0700506 return n;
507}
508
Craig Tillera82950e2015-09-22 12:33:20 -0700509static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx,
510 grpc_server *server) {
Craig Tiller1191e212015-07-30 14:49:02 -0700511 registered_method *rm;
Craig Tillera82950e2015-09-22 12:33:20 -0700512 request_matcher_kill_requests(exec_ctx, server,
513 &server->unregistered_request_matcher);
514 request_matcher_zombify_all_pending_calls(
515 exec_ctx, &server->unregistered_request_matcher);
516 for (rm = server->registered_methods; rm; rm = rm->next) {
517 request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher);
518 request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
519 }
Craig Tillerdc627722015-05-26 15:27:02 -0700520}
521
Craig Tillera82950e2015-09-22 12:33:20 -0700522static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
523 grpc_server *server) {
Craig Tiller45724b32015-09-22 10:42:19 -0700524 size_t i;
Craig Tillera82950e2015-09-22 12:33:20 -0700525 if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) {
526 return;
527 }
Craig Tiller45724b32015-09-22 10:42:19 -0700528
Craig Tillera82950e2015-09-22 12:33:20 -0700529 kill_pending_work_locked(exec_ctx, server);
Craig Tiller45724b32015-09-22 10:42:19 -0700530
Craig Tillera82950e2015-09-22 12:33:20 -0700531 if (server->root_channel_data.next != &server->root_channel_data ||
532 server->listeners_destroyed < num_listeners(server)) {
533 if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
534 server->last_shutdown_message_time),
535 gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
536 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
537 gpr_log(GPR_DEBUG,
538 "Waiting for %d channels and %d/%d listeners to be destroyed"
539 " before shutting down server",
540 num_channels(server),
541 num_listeners(server) - server->listeners_destroyed,
542 num_listeners(server));
Craig Tiller45724b32015-09-22 10:42:19 -0700543 }
Craig Tillera82950e2015-09-22 12:33:20 -0700544 return;
545 }
Craig Tiller45724b32015-09-22 10:42:19 -0700546 server->shutdown_published = 1;
Craig Tillera82950e2015-09-22 12:33:20 -0700547 for (i = 0; i < server->num_shutdown_tags; i++) {
548 server_ref(server);
549 grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq,
550 server->shutdown_tags[i].tag, 1, done_shutdown_event, server,
551 &server->shutdown_tags[i].completion);
552 }
Craig Tiller45724b32015-09-22 10:42:19 -0700553}
554
Craig Tillera82950e2015-09-22 12:33:20 -0700555static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
Craig Tiller6902ad22015-04-16 08:01:49 -0700556 grpc_call_element *elem = user_data;
Craig Tillercce17ac2015-01-20 09:29:28 -0800557 call_data *calld = elem->call_data;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800558 if (md->key == GRPC_MDSTR_PATH) {
Craig Tillera82950e2015-09-22 12:33:20 -0700559 calld->path = GRPC_MDSTR_REF(md->value);
560 return NULL;
Craig Tillerebdef9d2015-11-19 17:09:49 -0800561 } else if (md->key == GRPC_MDSTR_AUTHORITY) {
Craig Tillera82950e2015-09-22 12:33:20 -0700562 calld->host = GRPC_MDSTR_REF(md->value);
563 return NULL;
564 }
Craig Tiller6902ad22015-04-16 08:01:49 -0700565 return md;
566}
567
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800568static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
Craig Tiller6c396862016-01-28 13:53:40 -0800569 bool success) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700570 grpc_call_element *elem = ptr;
Craig Tiller6902ad22015-04-16 08:01:49 -0700571 call_data *calld = elem->call_data;
Craig Tiller94329d02015-07-23 09:52:11 -0700572 gpr_timespec op_deadline;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700573
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800574 grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem);
575 op_deadline = calld->recv_initial_metadata->deadline;
576 if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
577 calld->deadline = op_deadline;
578 }
579 if (calld->host && calld->path) {
580 /* do nothing */
581 } else {
582 success = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700583 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700584
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800585 calld->on_done_recv_initial_metadata->cb(
586 exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success);
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700587}
588
Craig Tillera82950e2015-09-22 12:33:20 -0700589static void server_mutate_op(grpc_call_element *elem,
590 grpc_transport_stream_op *op) {
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700591 call_data *calld = elem->call_data;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700592
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800593 if (op->recv_initial_metadata != NULL) {
594 calld->recv_initial_metadata = op->recv_initial_metadata;
Craig Tillera44cbfc2016-02-03 16:02:49 -0800595 calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
596 op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -0700597 }
Craig Tiller50d9db52015-04-23 10:52:14 -0700598}
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700599
Craig Tillera82950e2015-09-22 12:33:20 -0700600static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
601 grpc_call_element *elem,
602 grpc_transport_stream_op *op) {
603 GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
604 server_mutate_op(elem, op);
605 grpc_call_next_op(exec_ctx, elem, op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800606}
607
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800608static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
Craig Tiller6c396862016-01-28 13:53:40 -0800609 bool success) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800610 grpc_call_element *elem = ptr;
611 call_data *calld = elem->call_data;
612 if (success) {
613 start_new_rpc(exec_ctx, elem);
614 } else {
615 gpr_mu_lock(&calld->mu_state);
616 if (calld->state == NOT_STARTED) {
617 calld->state = ZOMBIED;
618 gpr_mu_unlock(&calld->mu_state);
619 grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller6c396862016-01-28 13:53:40 -0800620 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800621 } else if (calld->state == PENDING) {
622 calld->state = ZOMBIED;
623 gpr_mu_unlock(&calld->mu_state);
624 /* zombied call will be destroyed when it's removed from the pending
625 queue... later */
626 } else {
627 gpr_mu_unlock(&calld->mu_state);
628 }
629 }
630}
631
632static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
633 grpc_transport *transport,
Craig Tillera82950e2015-09-22 12:33:20 -0700634 const void *transport_server_data) {
Craig Tillere039f032015-06-25 12:54:23 -0700635 channel_data *chand = cd;
636 /* create a call */
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800637 grpc_call *call =
638 grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data,
639 NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
640 grpc_call_element *elem =
641 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
642 call_data *calld = elem->call_data;
643 grpc_op op;
644 memset(&op, 0, sizeof(op));
645 op.op = GRPC_OP_RECV_INITIAL_METADATA;
646 op.data.recv_initial_metadata = &calld->initial_metadata;
647 grpc_closure_init(&calld->got_initial_metadata, got_initial_metadata, elem);
648 grpc_call_start_batch_and_execute(exec_ctx, call, &op, 1,
649 &calld->got_initial_metadata);
Craig Tillere039f032015-06-25 12:54:23 -0700650}
651
Craig Tillera82950e2015-09-22 12:33:20 -0700652static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd,
Craig Tiller6c396862016-01-28 13:53:40 -0800653 bool iomgr_status_ignored) {
Craig Tillere039f032015-06-25 12:54:23 -0700654 channel_data *chand = cd;
655 grpc_server *server = chand->server;
Craig Tillera82950e2015-09-22 12:33:20 -0700656 if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
657 grpc_transport_op op;
658 memset(&op, 0, sizeof(op));
659 op.on_connectivity_state_change = &chand->channel_connectivity_changed,
660 op.connectivity_state = &chand->connectivity_state;
661 grpc_channel_next_op(exec_ctx,
662 grpc_channel_stack_element(
663 grpc_channel_get_channel_stack(chand->channel), 0),
664 &op);
665 } else {
666 gpr_mu_lock(&server->mu_global);
667 destroy_channel(exec_ctx, chand);
668 gpr_mu_unlock(&server->mu_global);
669 GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity");
670 }
Craig Tillere039f032015-06-25 12:54:23 -0700671}
672
Craig Tillera82950e2015-09-22 12:33:20 -0700673static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800674 grpc_call_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800675 call_data *calld = elem->call_data;
676 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700677 memset(calld, 0, sizeof(call_data));
678 calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
679 calld->call = grpc_call_from_top_element(elem);
680 gpr_mu_init(&calld->mu_state);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800681
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800682 grpc_closure_init(&calld->server_on_recv_initial_metadata,
683 server_on_recv_initial_metadata, elem);
Craig Tiller1e6facb2015-06-11 22:47:11 -0700684
Craig Tillera82950e2015-09-22 12:33:20 -0700685 server_ref(chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800686}
687
Craig Tillera82950e2015-09-22 12:33:20 -0700688static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
689 grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800690 channel_data *chand = elem->channel_data;
Craig Tillerdb7db992015-01-29 11:19:01 -0800691 call_data *calld = elem->call_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800692
Craig Tillera82950e2015-09-22 12:33:20 -0700693 GPR_ASSERT(calld->state != PENDING);
Craig Tiller092d8d12015-07-04 22:35:00 -0700694
Craig Tillera82950e2015-09-22 12:33:20 -0700695 if (calld->host) {
696 GRPC_MDSTR_UNREF(calld->host);
697 }
698 if (calld->path) {
699 GRPC_MDSTR_UNREF(calld->path);
700 }
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800701 grpc_metadata_array_destroy(&calld->initial_metadata);
Craig Tiller4df31a62015-01-30 09:44:31 -0800702
Craig Tillera82950e2015-09-22 12:33:20 -0700703 gpr_mu_destroy(&calld->mu_state);
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700704
Craig Tillera82950e2015-09-22 12:33:20 -0700705 server_unref(exec_ctx, chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800706}
707
Craig Tillera82950e2015-09-22 12:33:20 -0700708static void init_channel_elem(grpc_exec_ctx *exec_ctx,
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800709 grpc_channel_element *elem,
710 grpc_channel_element_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800711 channel_data *chand = elem->channel_data;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800712 GPR_ASSERT(args->is_first);
713 GPR_ASSERT(!args->is_last);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800714 chand->server = NULL;
715 chand->channel = NULL;
716 chand->next = chand->prev = chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800717 chand->registered_methods = NULL;
Craig Tillere039f032015-06-25 12:54:23 -0700718 chand->connectivity_state = GRPC_CHANNEL_IDLE;
Craig Tillera82950e2015-09-22 12:33:20 -0700719 grpc_closure_init(&chand->channel_connectivity_changed,
720 channel_connectivity_changed, chand);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800721}
722
Craig Tillera82950e2015-09-22 12:33:20 -0700723static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
724 grpc_channel_element *elem) {
Craig Tillerec3257c2015-02-12 15:59:43 -0800725 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800726 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -0700727 if (chand->registered_methods) {
728 for (i = 0; i < chand->registered_method_slots; i++) {
729 if (chand->registered_methods[i].method) {
730 GRPC_MDSTR_UNREF(chand->registered_methods[i].method);
731 }
732 if (chand->registered_methods[i].host) {
733 GRPC_MDSTR_UNREF(chand->registered_methods[i].host);
734 }
Craig Tillerec3257c2015-02-12 15:59:43 -0800735 }
Craig Tillera82950e2015-09-22 12:33:20 -0700736 gpr_free(chand->registered_methods);
737 }
738 if (chand->server) {
739 gpr_mu_lock(&chand->server->mu_global);
740 chand->next->prev = chand->prev;
741 chand->prev->next = chand->next;
742 chand->next = chand->prev = chand;
743 maybe_finish_shutdown(exec_ctx, chand->server);
744 gpr_mu_unlock(&chand->server->mu_global);
Craig Tillera82950e2015-09-22 12:33:20 -0700745 server_unref(exec_ctx, chand->server);
746 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800747}
748
Craig Tiller178edfa2016-02-17 20:54:46 -0800749const grpc_channel_filter grpc_server_top_filter = {
Craig Tiller71a0f9d2015-09-28 17:22:01 -0700750 server_start_transport_stream_op, grpc_channel_next_op, sizeof(call_data),
Craig Tillerc7e1a2a2015-11-02 14:17:32 -0800751 init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem,
752 sizeof(channel_data), init_channel_elem, destroy_channel_elem,
753 grpc_call_next_get_peer, "server",
Craig Tiller9f28ac22015-01-27 17:01:29 -0800754};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800755
Craig Tillera82950e2015-09-22 12:33:20 -0700756void grpc_server_register_completion_queue(grpc_server *server,
757 grpc_completion_queue *cq,
758 void *reserved) {
Craig Tiller20bc56d2015-02-12 09:02:56 -0800759 size_t i, n;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700760 GRPC_API_TRACE(
761 "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
762 (server, cq, reserved));
Craig Tillera82950e2015-09-22 12:33:20 -0700763 GPR_ASSERT(!reserved);
764 for (i = 0; i < server->cq_count; i++) {
765 if (server->cqs[i] == cq) return;
766 }
767 GRPC_CQ_INTERNAL_REF(cq, "server");
768 grpc_cq_mark_server_cq(cq);
Craig Tiller20bc56d2015-02-12 09:02:56 -0800769 n = server->cq_count++;
Craig Tillera82950e2015-09-22 12:33:20 -0700770 server->cqs = gpr_realloc(server->cqs,
771 server->cq_count * sizeof(grpc_completion_queue *));
Craig Tiller20bc56d2015-02-12 09:02:56 -0800772 server->cqs[n] = cq;
773}
774
Craig Tiller178edfa2016-02-17 20:54:46 -0800775grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800776 size_t i;
Craig Tiller178edfa2016-02-17 20:54:46 -0800777
778 GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800779
Craig Tillera82950e2015-09-22 12:33:20 -0700780 grpc_server *server = gpr_malloc(sizeof(grpc_server));
Craig Tiller60fd3612015-03-05 16:24:22 -0800781
Craig Tillera82950e2015-09-22 12:33:20 -0700782 GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
Craig Tiller60fd3612015-03-05 16:24:22 -0800783
Craig Tillera82950e2015-09-22 12:33:20 -0700784 memset(server, 0, sizeof(grpc_server));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800785
Craig Tillera82950e2015-09-22 12:33:20 -0700786 gpr_mu_init(&server->mu_global);
787 gpr_mu_init(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800788
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800789 /* decremented by grpc_server_destroy */
Craig Tillera82950e2015-09-22 12:33:20 -0700790 gpr_ref_init(&server->internal_refcount, 1);
791 server->root_channel_data.next = server->root_channel_data.prev =
792 &server->root_channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800793
Craig Tiller6a006ce2015-07-13 16:25:40 -0700794 /* TODO(ctiller): expose a channel_arg for this */
795 server->max_requested_calls = 32768;
Craig Tillera82950e2015-09-22 12:33:20 -0700796 server->request_freelist =
797 gpr_stack_lockfree_create(server->max_requested_calls);
798 for (i = 0; i < (size_t)server->max_requested_calls; i++) {
799 gpr_stack_lockfree_push(server->request_freelist, (int)i);
800 }
801 request_matcher_init(&server->unregistered_request_matcher,
802 server->max_requested_calls);
803 server->requested_calls = gpr_malloc(server->max_requested_calls *
804 sizeof(*server->requested_calls));
Craig Tiller729b35a2015-07-13 12:36:47 -0700805
Craig Tillera82950e2015-09-22 12:33:20 -0700806 server->channel_args = grpc_channel_args_copy(args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800807
808 return server;
809}
810
Craig Tillera82950e2015-09-22 12:33:20 -0700811static int streq(const char *a, const char *b) {
812 if (a == NULL && b == NULL) return 1;
813 if (a == NULL) return 0;
814 if (b == NULL) return 0;
815 return 0 == strcmp(a, b);
Craig Tiller24be0f72015-02-10 14:04:22 -0800816}
817
Craig Tillera82950e2015-09-22 12:33:20 -0700818void *grpc_server_register_method(grpc_server *server, const char *method,
819 const char *host) {
Craig Tiller24be0f72015-02-10 14:04:22 -0800820 registered_method *m;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700821 GRPC_API_TRACE("grpc_server_register_method(server=%p, method=%s, host=%s)",
822 3, (server, method, host));
Craig Tillera82950e2015-09-22 12:33:20 -0700823 if (!method) {
824 gpr_log(GPR_ERROR,
825 "grpc_server_register_method method string cannot be NULL");
826 return NULL;
827 }
828 for (m = server->registered_methods; m; m = m->next) {
829 if (streq(m->method, method) && streq(m->host, host)) {
830 gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
831 host ? host : "*");
Craig Tiller24be0f72015-02-10 14:04:22 -0800832 return NULL;
833 }
Craig Tillera82950e2015-09-22 12:33:20 -0700834 }
835 m = gpr_malloc(sizeof(registered_method));
836 memset(m, 0, sizeof(*m));
837 request_matcher_init(&m->request_matcher, server->max_requested_calls);
838 m->method = gpr_strdup(method);
839 m->host = gpr_strdup(host);
Craig Tiller24be0f72015-02-10 14:04:22 -0800840 m->next = server->registered_methods;
841 server->registered_methods = m;
842 return m;
843}
844
Craig Tillera82950e2015-09-22 12:33:20 -0700845void grpc_server_start(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800846 listener *l;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800847 size_t i;
Craig Tillerf5768a62015-09-22 10:54:34 -0700848 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800849
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700850 GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
851
Craig Tillera82950e2015-09-22 12:33:20 -0700852 server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
853 for (i = 0; i < server->cq_count; i++) {
854 server->pollsets[i] = grpc_cq_pollset(server->cqs[i]);
855 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800856
Craig Tillera82950e2015-09-22 12:33:20 -0700857 for (l = server->listeners; l; l = l->next) {
858 l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count);
859 }
Craig Tillerdfff1b82015-09-21 14:39:57 -0700860
Craig Tillera82950e2015-09-22 12:33:20 -0700861 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800862}
863
Craig Tillera82950e2015-09-22 12:33:20 -0700864void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
865 grpc_transport *transport,
Craig Tillera82950e2015-09-22 12:33:20 -0700866 const grpc_channel_args *args) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800867 size_t i;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800868 size_t num_registered_methods;
869 size_t alloc;
870 registered_method *rm;
871 channel_registered_method *crm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800872 grpc_channel *channel;
873 channel_data *chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800874 grpc_mdstr *host;
875 grpc_mdstr *method;
Craig Tiller7536af02015-12-22 13:49:30 -0800876 uint32_t hash;
Craig Tillerf96dfc32015-09-10 14:43:18 -0700877 size_t slots;
Craig Tiller7536af02015-12-22 13:49:30 -0800878 uint32_t probes;
879 uint32_t max_probes = 0;
Craig Tillere039f032015-06-25 12:54:23 -0700880 grpc_transport_op op;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800881
Craig Tillera82950e2015-09-22 12:33:20 -0700882 for (i = 0; i < s->cq_count; i++) {
883 memset(&op, 0, sizeof(op));
884 op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
885 grpc_transport_perform_op(exec_ctx, transport, &op);
886 }
ctillerd79b4862014-12-17 16:36:59 -0800887
Craig Tiller178edfa2016-02-17 20:54:46 -0800888 channel =
889 grpc_channel_create(exec_ctx, NULL, args, GRPC_SERVER_CHANNEL, transport);
Craig Tillera82950e2015-09-22 12:33:20 -0700890 chand = (channel_data *)grpc_channel_stack_element(
Craig Tiller71a0f9d2015-09-28 17:22:01 -0700891 grpc_channel_get_channel_stack(channel), 0)->channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800892 chand->server = s;
Craig Tillera82950e2015-09-22 12:33:20 -0700893 server_ref(s);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800894 chand->channel = channel;
895
Craig Tiller04cc8be2015-02-10 16:11:22 -0800896 num_registered_methods = 0;
Craig Tillera82950e2015-09-22 12:33:20 -0700897 for (rm = s->registered_methods; rm; rm = rm->next) {
898 num_registered_methods++;
899 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800900 /* build a lookup table phrased in terms of mdstr's in this channels context
901 to quickly find registered methods */
Craig Tillera82950e2015-09-22 12:33:20 -0700902 if (num_registered_methods > 0) {
903 slots = 2 * num_registered_methods;
904 alloc = sizeof(channel_registered_method) * slots;
905 chand->registered_methods = gpr_malloc(alloc);
906 memset(chand->registered_methods, 0, alloc);
907 for (rm = s->registered_methods; rm; rm = rm->next) {
Craig Tillerb2b42612015-11-20 12:02:17 -0800908 host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL;
909 method = grpc_mdstr_from_string(rm->method);
Craig Tillera82950e2015-09-22 12:33:20 -0700910 hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
911 for (probes = 0; chand->registered_methods[(hash + probes) % slots]
Craig Tiller71a0f9d2015-09-28 17:22:01 -0700912 .server_registered_method != NULL;
Craig Tillera82950e2015-09-22 12:33:20 -0700913 probes++)
914 ;
915 if (probes > max_probes) max_probes = probes;
916 crm = &chand->registered_methods[(hash + probes) % slots];
917 crm->server_registered_method = rm;
918 crm->host = host;
919 crm->method = method;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800920 }
Craig Tiller7536af02015-12-22 13:49:30 -0800921 GPR_ASSERT(slots <= UINT32_MAX);
922 chand->registered_method_slots = (uint32_t)slots;
Craig Tillera82950e2015-09-22 12:33:20 -0700923 chand->registered_method_max_probes = max_probes;
924 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800925
Craig Tillera82950e2015-09-22 12:33:20 -0700926 gpr_mu_lock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800927 chand->next = &s->root_channel_data;
928 chand->prev = chand->next->prev;
929 chand->next->prev = chand->prev->next = chand;
Craig Tillera82950e2015-09-22 12:33:20 -0700930 gpr_mu_unlock(&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800931
Craig Tillera82950e2015-09-22 12:33:20 -0700932 GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity");
933 memset(&op, 0, sizeof(op));
Craig Tiller4b804102015-06-26 16:16:12 -0700934 op.set_accept_stream = accept_stream;
935 op.set_accept_stream_user_data = chand;
936 op.on_connectivity_state_change = &chand->channel_connectivity_changed;
937 op.connectivity_state = &chand->connectivity_state;
Craig Tillera82950e2015-09-22 12:33:20 -0700938 op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0;
939 grpc_transport_perform_op(exec_ctx, transport, &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800940}
941
Craig Tillera82950e2015-09-22 12:33:20 -0700942void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg,
943 grpc_cq_completion *storage) {
944 (void)done_arg;
945 gpr_free(storage);
murgatroid9900a3dab2015-08-19 11:15:38 -0700946}
947
Craig Tillera82950e2015-09-22 12:33:20 -0700948static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s,
Craig Tiller6c396862016-01-28 13:53:40 -0800949 bool success) {
Craig Tillerdfff1b82015-09-21 14:39:57 -0700950 grpc_server *server = s;
Craig Tillera82950e2015-09-22 12:33:20 -0700951 gpr_mu_lock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700952 server->listeners_destroyed++;
Craig Tillera82950e2015-09-22 12:33:20 -0700953 maybe_finish_shutdown(exec_ctx, server);
954 gpr_mu_unlock(&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -0700955}
956
Craig Tillera82950e2015-09-22 12:33:20 -0700957void grpc_server_shutdown_and_notify(grpc_server *server,
958 grpc_completion_queue *cq, void *tag) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800959 listener *l;
Craig Tillerbce999f2015-05-27 09:55:51 -0700960 shutdown_tag *sdt;
Craig Tillerff3ae682015-06-29 17:44:04 -0700961 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -0700962 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800963
Masood Malekghassemi76c3d742015-08-19 18:22:53 -0700964 GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3,
965 (server, cq, tag));
966
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800967 /* lock, and gather up some stuff to do */
Craig Tillera82950e2015-09-22 12:33:20 -0700968 gpr_mu_lock(&server->mu_global);
Craig Tiller4bf29282015-12-14 11:25:48 -0800969 grpc_cq_begin_op(cq, tag);
Craig Tillera82950e2015-09-22 12:33:20 -0700970 if (server->shutdown_published) {
971 grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL,
972 gpr_malloc(sizeof(grpc_cq_completion)));
973 gpr_mu_unlock(&server->mu_global);
974 goto done;
975 }
976 server->shutdown_tags =
977 gpr_realloc(server->shutdown_tags,
978 sizeof(shutdown_tag) * (server->num_shutdown_tags + 1));
Craig Tillerbce999f2015-05-27 09:55:51 -0700979 sdt = &server->shutdown_tags[server->num_shutdown_tags++];
980 sdt->tag = tag;
981 sdt->cq = cq;
Craig Tillera82950e2015-09-22 12:33:20 -0700982 if (gpr_atm_acq_load(&server->shutdown_flag)) {
983 gpr_mu_unlock(&server->mu_global);
984 goto done;
985 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800986
Craig Tillera82950e2015-09-22 12:33:20 -0700987 server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
Craig Tillerab54f792015-07-08 08:34:20 -0700988
Craig Tillera82950e2015-09-22 12:33:20 -0700989 channel_broadcaster_init(server, &broadcaster);
nnoble0c475f02014-12-05 15:37:39 -0800990
Craig Tillerfc193e12015-09-24 15:29:03 -0700991 gpr_atm_rel_store(&server->shutdown_flag, 1);
992
Craig Tillerbd217572015-02-11 18:10:56 -0800993 /* collect all unregistered then registered calls */
Craig Tillera82950e2015-09-22 12:33:20 -0700994 gpr_mu_lock(&server->mu_call);
995 kill_pending_work_locked(&exec_ctx, server);
996 gpr_mu_unlock(&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800997
Craig Tillera82950e2015-09-22 12:33:20 -0700998 maybe_finish_shutdown(&exec_ctx, server);
999 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001000
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001001 /* Shutdown listeners */
Craig Tillera82950e2015-09-22 12:33:20 -07001002 for (l = server->listeners; l; l = l->next) {
1003 grpc_closure_init(&l->destroy_done, listener_destroy_done, server);
1004 l->destroy(&exec_ctx, server, l->arg, &l->destroy_done);
1005 }
Craig Tillerff3ae682015-06-29 17:44:04 -07001006
Craig Tillera82950e2015-09-22 12:33:20 -07001007 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001008
Craig Tillerdfff1b82015-09-21 14:39:57 -07001009done:
Craig Tillera82950e2015-09-22 12:33:20 -07001010 grpc_exec_ctx_finish(&exec_ctx);
Craig Tilleraec96aa2015-04-07 14:32:15 -07001011}
1012
Craig Tillera82950e2015-09-22 12:33:20 -07001013void grpc_server_cancel_all_calls(grpc_server *server) {
Craig Tiller092d8d12015-07-04 22:35:00 -07001014 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001015 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillerafa2d632015-05-26 16:39:13 -07001016
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001017 GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server));
1018
Craig Tillera82950e2015-09-22 12:33:20 -07001019 gpr_mu_lock(&server->mu_global);
1020 channel_broadcaster_init(server, &broadcaster);
1021 gpr_mu_unlock(&server->mu_global);
Craig Tillerafa2d632015-05-26 16:39:13 -07001022
Craig Tillera82950e2015-09-22 12:33:20 -07001023 channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1);
1024 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerafa2d632015-05-26 16:39:13 -07001025}
1026
Craig Tillera82950e2015-09-22 12:33:20 -07001027void grpc_server_destroy(grpc_server *server) {
Craig Tilleraec96aa2015-04-07 14:32:15 -07001028 listener *l;
Craig Tillerf5768a62015-09-22 10:54:34 -07001029 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller872af022015-04-24 15:57:52 -07001030
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001031 GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server));
1032
Craig Tillera82950e2015-09-22 12:33:20 -07001033 gpr_mu_lock(&server->mu_global);
1034 GPR_ASSERT(gpr_atm_acq_load(&server->shutdown_flag) || !server->listeners);
1035 GPR_ASSERT(server->listeners_destroyed == num_listeners(server));
Craig Tilleraec96aa2015-04-07 14:32:15 -07001036
Craig Tillera82950e2015-09-22 12:33:20 -07001037 while (server->listeners) {
1038 l = server->listeners;
1039 server->listeners = l->next;
1040 gpr_free(l);
1041 }
Craig Tilleraec96aa2015-04-07 14:32:15 -07001042
Craig Tillera82950e2015-09-22 12:33:20 -07001043 gpr_mu_unlock(&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001044
Craig Tillera82950e2015-09-22 12:33:20 -07001045 server_unref(&exec_ctx, server);
1046 grpc_exec_ctx_finish(&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001047}
1048
Craig Tillera82950e2015-09-22 12:33:20 -07001049void grpc_server_add_listener(
1050 grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1051 void (*start)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1052 grpc_pollset **pollsets, size_t pollset_count),
1053 void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_server *server, void *arg,
1054 grpc_closure *on_done)) {
1055 listener *l = gpr_malloc(sizeof(listener));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001056 l->arg = arg;
1057 l->start = start;
1058 l->destroy = destroy;
1059 l->next = server->listeners;
1060 server->listeners = l;
1061}
1062
Craig Tillera82950e2015-09-22 12:33:20 -07001063static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
1064 grpc_server *server,
1065 requested_call *rc) {
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001066 call_data *calld = NULL;
Craig Tillerb9d35962015-09-11 13:31:16 -07001067 request_matcher *rm = NULL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001068 int request_id;
Craig Tillera82950e2015-09-22 12:33:20 -07001069 if (gpr_atm_acq_load(&server->shutdown_flag)) {
1070 fail_call(exec_ctx, server, rc);
1071 return GRPC_CALL_OK;
1072 }
1073 request_id = gpr_stack_lockfree_pop(server->request_freelist);
1074 if (request_id == -1) {
1075 /* out of request ids: just fail this one */
1076 fail_call(exec_ctx, server, rc);
1077 return GRPC_CALL_OK;
1078 }
1079 switch (rc->type) {
Craig Tiller04cc8be2015-02-10 16:11:22 -08001080 case BATCH_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001081 rm = &server->unregistered_request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001082 break;
1083 case REGISTERED_CALL:
Craig Tillerb9d35962015-09-11 13:31:16 -07001084 rm = &rc->data.registered.registered_method->request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001085 break;
Craig Tillera82950e2015-09-22 12:33:20 -07001086 }
Craig Tiller45724b32015-09-22 10:42:19 -07001087 server->requested_calls[request_id] = *rc;
Craig Tillera82950e2015-09-22 12:33:20 -07001088 gpr_free(rc);
Craig Tillerb9d35962015-09-11 13:31:16 -07001089 if (gpr_stack_lockfree_push(rm->requests, request_id)) {
Craig Tillera82950e2015-09-22 12:33:20 -07001090 /* this was the first queued request: we need to lock and start
1091 matching calls */
1092 gpr_mu_lock(&server->mu_call);
Craig Tillerb9d35962015-09-11 13:31:16 -07001093 while ((calld = rm->pending_head) != NULL) {
1094 request_id = gpr_stack_lockfree_pop(rm->requests);
Craig Tillera82950e2015-09-22 12:33:20 -07001095 if (request_id == -1) break;
Craig Tillerb9d35962015-09-11 13:31:16 -07001096 rm->pending_head = calld->pending_next;
Craig Tillera82950e2015-09-22 12:33:20 -07001097 gpr_mu_unlock(&server->mu_call);
1098 gpr_mu_lock(&calld->mu_state);
1099 if (calld->state == ZOMBIED) {
1100 gpr_mu_unlock(&calld->mu_state);
1101 grpc_closure_init(
1102 &calld->kill_zombie_closure, kill_zombie,
1103 grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
Craig Tiller6c396862016-01-28 13:53:40 -08001104 grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true,
1105 NULL);
Craig Tillera82950e2015-09-22 12:33:20 -07001106 } else {
1107 GPR_ASSERT(calld->state == PENDING);
1108 calld->state = ACTIVATED;
1109 gpr_mu_unlock(&calld->mu_state);
1110 begin_call(exec_ctx, server, calld,
1111 &server->requested_calls[request_id]);
1112 }
1113 gpr_mu_lock(&server->mu_call);
Craig Tiller45724b32015-09-22 10:42:19 -07001114 }
Craig Tillera82950e2015-09-22 12:33:20 -07001115 gpr_mu_unlock(&server->mu_call);
1116 }
Craig Tiller6a006ce2015-07-13 16:25:40 -07001117 return GRPC_CALL_OK;
Craig Tillercce17ac2015-01-20 09:29:28 -08001118}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001119
Craig Tillera82950e2015-09-22 12:33:20 -07001120grpc_call_error grpc_server_request_call(
1121 grpc_server *server, grpc_call **call, grpc_call_details *details,
1122 grpc_metadata_array *initial_metadata,
1123 grpc_completion_queue *cq_bound_to_call,
1124 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001125 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001126 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001127 requested_call *rc = gpr_malloc(sizeof(*rc));
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001128 GRPC_API_TRACE(
1129 "grpc_server_request_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001130 "server=%p, call=%p, details=%p, initial_metadata=%p, "
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001131 "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001132 7, (server, call, details, initial_metadata, cq_bound_to_call,
1133 cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001134 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1135 gpr_free(rc);
1136 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1137 goto done;
1138 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001139 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller9928d392015-08-18 09:40:24 -07001140 details->reserved = NULL;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001141 rc->type = BATCH_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001142 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001143 rc->tag = tag;
1144 rc->cq_bound_to_call = cq_bound_to_call;
1145 rc->cq_for_notification = cq_for_notification;
1146 rc->call = call;
1147 rc->data.batch.details = details;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001148 rc->initial_metadata = initial_metadata;
Craig Tillera82950e2015-09-22 12:33:20 -07001149 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001150done:
Craig Tillera82950e2015-09-22 12:33:20 -07001151 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001152 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001153}
1154
Craig Tillera82950e2015-09-22 12:33:20 -07001155grpc_call_error grpc_server_request_registered_call(
Craig Tillerb9d35962015-09-11 13:31:16 -07001156 grpc_server *server, void *rmp, grpc_call **call, gpr_timespec *deadline,
Craig Tillera82950e2015-09-22 12:33:20 -07001157 grpc_metadata_array *initial_metadata, grpc_byte_buffer **optional_payload,
1158 grpc_completion_queue *cq_bound_to_call,
1159 grpc_completion_queue *cq_for_notification, void *tag) {
Craig Tillerdfff1b82015-09-21 14:39:57 -07001160 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001161 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillera82950e2015-09-22 12:33:20 -07001162 requested_call *rc = gpr_malloc(sizeof(*rc));
Craig Tillerb9d35962015-09-11 13:31:16 -07001163 registered_method *rm = rmp;
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001164 GRPC_API_TRACE(
1165 "grpc_server_request_registered_call("
Craig Tiller4de3e4f2015-10-05 08:55:50 -07001166 "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, "
1167 "optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
1168 "tag=%p)",
Masood Malekghassemi76c3d742015-08-19 18:22:53 -07001169 9, (server, rmp, call, deadline, initial_metadata, optional_payload,
1170 cq_bound_to_call, cq_for_notification, tag));
Craig Tillera82950e2015-09-22 12:33:20 -07001171 if (!grpc_cq_is_server_cq(cq_for_notification)) {
1172 gpr_free(rc);
1173 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1174 goto done;
1175 }
Craig Tiller4bf29282015-12-14 11:25:48 -08001176 grpc_cq_begin_op(cq_for_notification, tag);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001177 rc->type = REGISTERED_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001178 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001179 rc->tag = tag;
1180 rc->cq_bound_to_call = cq_bound_to_call;
1181 rc->cq_for_notification = cq_for_notification;
1182 rc->call = call;
Craig Tillerb9d35962015-09-11 13:31:16 -07001183 rc->data.registered.registered_method = rm;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001184 rc->data.registered.deadline = deadline;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001185 rc->initial_metadata = initial_metadata;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001186 rc->data.registered.optional_payload = optional_payload;
Craig Tillera82950e2015-09-22 12:33:20 -07001187 error = queue_call_request(&exec_ctx, server, rc);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001188done:
Craig Tillera82950e2015-09-22 12:33:20 -07001189 grpc_exec_ctx_finish(&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001190 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001191}
1192
Craig Tillera82950e2015-09-22 12:33:20 -07001193static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx,
Craig Tiller6c396862016-01-28 13:53:40 -08001194 void *user_data, bool success);
Craig Tiller24be0f72015-02-10 14:04:22 -08001195
Craig Tillera82950e2015-09-22 12:33:20 -07001196static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
Craig Tiller166e2502015-02-03 20:14:41 -08001197 gpr_slice slice = value->slice;
Craig Tillera82950e2015-09-22 12:33:20 -07001198 size_t len = GPR_SLICE_LENGTH(slice);
Craig Tiller166e2502015-02-03 20:14:41 -08001199
Craig Tillera82950e2015-09-22 12:33:20 -07001200 if (len + 1 > *capacity) {
1201 *capacity = GPR_MAX(len + 1, *capacity * 2);
1202 *dest = gpr_realloc(*dest, *capacity);
1203 }
1204 memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
Craig Tiller166e2502015-02-03 20:14:41 -08001205}
1206
Craig Tillera82950e2015-09-22 12:33:20 -07001207static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1208 call_data *calld, requested_call *rc) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001209 grpc_op ops[1];
1210 grpc_op *op = ops;
1211
1212 memset(ops, 0, sizeof(ops));
Craig Tiller24be0f72015-02-10 14:04:22 -08001213
1214 /* called once initial metadata has been read by the call, but BEFORE
1215 the ioreq to fetch it out of the call has been executed.
1216 This means metadata related fields can be relied on in calld, but to
1217 fill in the metadata array passed by the client, we need to perform
1218 an ioreq op, that should complete immediately. */
1219
Craig Tillera82950e2015-09-22 12:33:20 -07001220 grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001221 grpc_closure_init(&rc->publish, publish_registered_or_batch, rc);
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001222 *rc->call = calld->call;
1223 calld->cq_new = rc->cq_for_notification;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001224 GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
Craig Tillera82950e2015-09-22 12:33:20 -07001225 switch (rc->type) {
Craig Tiller24be0f72015-02-10 14:04:22 -08001226 case BATCH_CALL:
Craig Tillera82950e2015-09-22 12:33:20 -07001227 GPR_ASSERT(calld->host != NULL);
1228 GPR_ASSERT(calld->path != NULL);
1229 cpstr(&rc->data.batch.details->host,
1230 &rc->data.batch.details->host_capacity, calld->host);
1231 cpstr(&rc->data.batch.details->method,
1232 &rc->data.batch.details->method_capacity, calld->path);
Masood Malekghassemibf177c82015-04-27 12:14:38 -07001233 rc->data.batch.details->deadline = calld->deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -08001234 break;
1235 case REGISTERED_CALL:
1236 *rc->data.registered.deadline = calld->deadline;
Craig Tillera82950e2015-09-22 12:33:20 -07001237 if (rc->data.registered.optional_payload) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001238 op->op = GRPC_OP_RECV_MESSAGE;
1239 op->data.recv_message = rc->data.registered.optional_payload;
1240 op++;
Craig Tillera82950e2015-09-22 12:33:20 -07001241 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001242 break;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001243 default:
1244 GPR_UNREACHABLE_CODE(return );
Craig Tillera82950e2015-09-22 12:33:20 -07001245 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001246
Craig Tillera82950e2015-09-22 12:33:20 -07001247 GRPC_CALL_INTERNAL_REF(calld->call, "server");
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001248 grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops,
1249 (size_t)(op - ops), &rc->publish);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001250}
1251
Craig Tillera82950e2015-09-22 12:33:20 -07001252static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
1253 grpc_cq_completion *c) {
Craig Tiller6a006ce2015-07-13 16:25:40 -07001254 requested_call *rc = req;
1255 grpc_server *server = rc->server;
1256
Craig Tillera82950e2015-09-22 12:33:20 -07001257 if (rc >= server->requested_calls &&
1258 rc < server->requested_calls + server->max_requested_calls) {
1259 GPR_ASSERT(rc - server->requested_calls <= INT_MAX);
1260 gpr_stack_lockfree_push(server->request_freelist,
1261 (int)(rc - server->requested_calls));
1262 } else {
1263 gpr_free(req);
1264 }
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001265
Craig Tillera82950e2015-09-22 12:33:20 -07001266 server_unref(exec_ctx, server);
Craig Tiller24be0f72015-02-10 14:04:22 -08001267}
1268
Craig Tillera82950e2015-09-22 12:33:20 -07001269static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
1270 requested_call *rc) {
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001271 *rc->call = NULL;
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001272 rc->initial_metadata->count = 0;
1273
Craig Tillera82950e2015-09-22 12:33:20 -07001274 server_ref(server);
1275 grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
1276 done_request_event, rc, &rc->completion);
Craig Tiller24be0f72015-02-10 14:04:22 -08001277}
1278
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001279static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc,
Craig Tiller6c396862016-01-28 13:53:40 -08001280 bool success) {
Craig Tillerc7e1a2a2015-11-02 14:17:32 -08001281 requested_call *rc = prc;
1282 grpc_call *call = *rc->call;
Craig Tillera82950e2015-09-22 12:33:20 -07001283 grpc_call_element *elem =
1284 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
Craig Tiller20bc56d2015-02-12 09:02:56 -08001285 call_data *calld = elem->call_data;
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001286 channel_data *chand = elem->channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001287 server_ref(chand->server);
1288 grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event,
1289 rc, &rc->completion);
1290 GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server");
Craig Tiller24be0f72015-02-10 14:04:22 -08001291}
1292
Craig Tillera82950e2015-09-22 12:33:20 -07001293const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001294 return server->channel_args;
Craig Tiller190d3602015-02-18 09:23:38 -08001295}
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001296
Craig Tillera82950e2015-09-22 12:33:20 -07001297int grpc_server_has_open_connections(grpc_server *server) {
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001298 int r;
Craig Tillera82950e2015-09-22 12:33:20 -07001299 gpr_mu_lock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001300 r = server->root_channel_data.next != &server->root_channel_data;
Craig Tillera82950e2015-09-22 12:33:20 -07001301 gpr_mu_unlock(&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001302 return r;
1303}