blob: 83fe3a7686da13b40f232dbef7cdf3d7da74636f [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include "src/core/surface/server.h"
35
Craig Tillerf96dfc32015-09-10 14:43:18 -070036#include <limits.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080037#include <stdlib.h>
38#include <string.h>
39
Craig Tiller6a006ce2015-07-13 16:25:40 -070040#include <grpc/support/alloc.h>
41#include <grpc/support/log.h>
42#include <grpc/support/string_util.h>
43#include <grpc/support/useful.h>
44
Hongyu Chene09dc782015-08-21 11:28:33 -070045#include "src/core/census/grpc_filter.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080046#include "src/core/channel/channel_args.h"
47#include "src/core/channel/connected_channel.h"
ctiller18b49ab2014-12-09 14:39:16 -080048#include "src/core/iomgr/iomgr.h"
Craig Tiller6a006ce2015-07-13 16:25:40 -070049#include "src/core/support/stack_lockfree.h"
Craig Tiller485d7762015-01-23 12:54:05 -080050#include "src/core/support/string.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080051#include "src/core/surface/call.h"
52#include "src/core/surface/channel.h"
53#include "src/core/surface/completion_queue.h"
Craig Tiller60fd3612015-03-05 16:24:22 -080054#include "src/core/surface/init.h"
Craig Tillercce17ac2015-01-20 09:29:28 -080055#include "src/core/transport/metadata.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080056
Craig Tiller45724b32015-09-22 10:42:19 -070057typedef struct listener
58{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080059 void *arg;
Craig Tiller1be70cc2015-09-22 10:45:28 -070060 void (*start) (grpc_exec_ctx * exec_ctx, grpc_server * server, void *arg, grpc_pollset ** pollsets, size_t pollset_count);
61 void (*destroy) (grpc_exec_ctx * exec_ctx, grpc_server * server, void *arg, grpc_closure * closure);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080062 struct listener *next;
Craig Tillerdfff1b82015-09-21 14:39:57 -070063 grpc_closure destroy_done;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080064} listener;
65
66typedef struct call_data call_data;
67typedef struct channel_data channel_data;
Craig Tiller24be0f72015-02-10 14:04:22 -080068typedef struct registered_method registered_method;
69
Craig Tiller45724b32015-09-22 10:42:19 -070070typedef struct
71{
Craig Tiller24be0f72015-02-10 14:04:22 -080072 call_data *next;
73 call_data *prev;
74} call_link;
75
Craig Tiller45724b32015-09-22 10:42:19 -070076typedef enum
77{ BATCH_CALL, REGISTERED_CALL } requested_call_type;
Craig Tiller24be0f72015-02-10 14:04:22 -080078
Craig Tiller45724b32015-09-22 10:42:19 -070079typedef struct requested_call
80{
Craig Tiller24be0f72015-02-10 14:04:22 -080081 requested_call_type type;
82 void *tag;
Craig Tiller6a006ce2015-07-13 16:25:40 -070083 grpc_server *server;
Craig Tillerf9e6adf2015-05-06 11:45:59 -070084 grpc_completion_queue *cq_bound_to_call;
85 grpc_completion_queue *cq_for_notification;
86 grpc_call **call;
Craig Tiller97fc6a32015-07-08 15:31:35 -070087 grpc_cq_completion completion;
Craig Tiller45724b32015-09-22 10:42:19 -070088 union
89 {
90 struct
91 {
Craig Tiller24be0f72015-02-10 14:04:22 -080092 grpc_call_details *details;
93 grpc_metadata_array *initial_metadata;
94 } batch;
Craig Tiller45724b32015-09-22 10:42:19 -070095 struct
96 {
Craig Tiller24be0f72015-02-10 14:04:22 -080097 registered_method *registered_method;
98 gpr_timespec *deadline;
99 grpc_metadata_array *initial_metadata;
100 grpc_byte_buffer **optional_payload;
101 } registered;
102 } data;
103} requested_call;
104
Craig Tiller45724b32015-09-22 10:42:19 -0700105typedef struct channel_registered_method
106{
Craig Tiller24be0f72015-02-10 14:04:22 -0800107 registered_method *server_registered_method;
108 grpc_mdstr *method;
109 grpc_mdstr *host;
110} channel_registered_method;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800111
Craig Tiller45724b32015-09-22 10:42:19 -0700112struct channel_data
113{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800114 grpc_server *server;
Craig Tillere039f032015-06-25 12:54:23 -0700115 grpc_connectivity_state connectivity_state;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800116 grpc_channel *channel;
Craig Tillercce17ac2015-01-20 09:29:28 -0800117 grpc_mdstr *path_key;
118 grpc_mdstr *authority_key;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800119 /* linked list of all channels on a server */
120 channel_data *next;
121 channel_data *prev;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800122 channel_registered_method *registered_methods;
123 gpr_uint32 registered_method_slots;
124 gpr_uint32 registered_method_max_probes;
Craig Tiller33825112015-09-18 07:44:19 -0700125 grpc_closure finish_destroy_channel_closure;
126 grpc_closure channel_connectivity_changed;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800127};
128
Craig Tiller45724b32015-09-22 10:42:19 -0700129typedef struct shutdown_tag
130{
Craig Tillerbce999f2015-05-27 09:55:51 -0700131 void *tag;
132 grpc_completion_queue *cq;
Craig Tiller97fc6a32015-07-08 15:31:35 -0700133 grpc_cq_completion completion;
Craig Tillerbce999f2015-05-27 09:55:51 -0700134} shutdown_tag;
135
Craig Tiller45724b32015-09-22 10:42:19 -0700136typedef enum
137{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800138 /* waiting for metadata */
139 NOT_STARTED,
140 /* inital metadata read, not flow controlled in yet */
141 PENDING,
142 /* flow controlled in, on completion queue */
143 ACTIVATED,
144 /* cancelled before being queued */
145 ZOMBIED
146} call_state;
147
Craig Tiller729b35a2015-07-13 12:36:47 -0700148typedef struct request_matcher request_matcher;
149
Craig Tiller45724b32015-09-22 10:42:19 -0700150struct call_data
151{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800152 grpc_call *call;
153
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700154 /** protects state */
155 gpr_mu mu_state;
156 /** the current state of a call - see call_state */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800157 call_state state;
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700158
Craig Tillercce17ac2015-01-20 09:29:28 -0800159 grpc_mdstr *path;
160 grpc_mdstr *host;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700161 gpr_timespec deadline;
162 int got_initial_metadata;
Craig Tillercce17ac2015-01-20 09:29:28 -0800163
Craig Tiller20bc56d2015-02-12 09:02:56 -0800164 grpc_completion_queue *cq_new;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800165
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700166 grpc_stream_op_buffer *recv_ops;
167 grpc_stream_state *recv_state;
Craig Tiller33825112015-09-18 07:44:19 -0700168 grpc_closure *on_done_recv;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700169
Craig Tiller33825112015-09-18 07:44:19 -0700170 grpc_closure server_on_recv;
171 grpc_closure kill_zombie_closure;
David Garcia Quintas284488b2015-05-28 16:27:39 -0700172
Craig Tiller729b35a2015-07-13 12:36:47 -0700173 call_data *pending_next;
174};
175
Craig Tiller45724b32015-09-22 10:42:19 -0700176struct request_matcher
177{
Craig Tiller729b35a2015-07-13 12:36:47 -0700178 call_data *pending_head;
179 call_data *pending_tail;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700180 gpr_stack_lockfree *requests;
Craig Tiller729b35a2015-07-13 12:36:47 -0700181};
182
Craig Tiller45724b32015-09-22 10:42:19 -0700183struct registered_method
184{
Craig Tiller729b35a2015-07-13 12:36:47 -0700185 char *method;
186 char *host;
187 request_matcher request_matcher;
188 registered_method *next;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800189};
190
Craig Tiller45724b32015-09-22 10:42:19 -0700191typedef struct
192{
Craig Tillerff3ae682015-06-29 17:44:04 -0700193 grpc_channel **channels;
194 size_t num_channels;
195} channel_broadcaster;
196
Craig Tiller45724b32015-09-22 10:42:19 -0700197struct grpc_server
198{
Craig Tiller729b35a2015-07-13 12:36:47 -0700199 size_t channel_filter_count;
200 const grpc_channel_filter **channel_filters;
201 grpc_channel_args *channel_args;
202
203 grpc_completion_queue **cqs;
204 grpc_pollset **pollsets;
205 size_t cq_count;
206
207 /* The two following mutexes control access to server-state
208 mu_global controls access to non-call-related state (e.g., channel state)
209 mu_call controls access to call-related state (e.g., the call lists)
210
211 If they are ever required to be nested, you must lock mu_global
212 before mu_call. This is currently used in shutdown processing
213 (grpc_server_shutdown_and_notify and maybe_finish_shutdown) */
Craig Tiller45724b32015-09-22 10:42:19 -0700214 gpr_mu mu_global; /* mutex for server and channel state */
215 gpr_mu mu_call; /* mutex for call-specific state */
Craig Tiller729b35a2015-07-13 12:36:47 -0700216
217 registered_method *registered_methods;
218 request_matcher unregistered_request_matcher;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700219 /** free list of available requested_calls indices */
220 gpr_stack_lockfree *request_freelist;
221 /** requested call backing data */
222 requested_call *requested_calls;
Craig Tiller32ca48c2015-09-10 11:47:15 -0700223 size_t max_requested_calls;
Craig Tiller729b35a2015-07-13 12:36:47 -0700224
Craig Tiller6a006ce2015-07-13 16:25:40 -0700225 gpr_atm shutdown_flag;
Craig Tiller729b35a2015-07-13 12:36:47 -0700226 gpr_uint8 shutdown_published;
227 size_t num_shutdown_tags;
228 shutdown_tag *shutdown_tags;
229
230 channel_data root_channel_data;
231
232 listener *listeners;
233 int listeners_destroyed;
234 gpr_refcount internal_refcount;
235
236 /** when did we print the last shutdown progress message */
237 gpr_timespec last_shutdown_message_time;
238};
239
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800240#define SERVER_FROM_CALL_ELEM(elem) \
241 (((channel_data *)(elem)->channel_data)->server)
242
Craig Tiller1be70cc2015-09-22 10:45:28 -0700243static void begin_call (grpc_exec_ctx * exec_ctx, grpc_server * server, call_data * calld, requested_call * rc);
244static void fail_call (grpc_exec_ctx * exec_ctx, grpc_server * server, requested_call * rc);
Vijay Pai8931cdd2015-06-17 12:42:17 -0700245/* Before calling maybe_finish_shutdown, we must hold mu_global and not
246 hold mu_call */
Craig Tiller1be70cc2015-09-22 10:45:28 -0700247static void maybe_finish_shutdown (grpc_exec_ctx * exec_ctx, grpc_server * server);
Craig Tiller24be0f72015-02-10 14:04:22 -0800248
Craig Tiller729b35a2015-07-13 12:36:47 -0700249/*
250 * channel broadcaster
251 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700252
253/* assumes server locked */
Craig Tiller45724b32015-09-22 10:42:19 -0700254static void
255channel_broadcaster_init (grpc_server * s, channel_broadcaster * cb)
256{
Craig Tillerff3ae682015-06-29 17:44:04 -0700257 channel_data *c;
258 size_t count = 0;
Craig Tiller45724b32015-09-22 10:42:19 -0700259 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next)
260 {
261 count++;
262 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700263 cb->num_channels = count;
Craig Tiller45724b32015-09-22 10:42:19 -0700264 cb->channels = gpr_malloc (sizeof (*cb->channels) * cb->num_channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700265 count = 0;
Craig Tiller45724b32015-09-22 10:42:19 -0700266 for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next)
267 {
268 cb->channels[count++] = c->channel;
269 GRPC_CHANNEL_INTERNAL_REF (c->channel, "broadcast");
270 }
Craig Tillerff3ae682015-06-29 17:44:04 -0700271}
272
Craig Tiller45724b32015-09-22 10:42:19 -0700273struct shutdown_cleanup_args
274{
Craig Tiller33825112015-09-18 07:44:19 -0700275 grpc_closure closure;
Craig Tillerff3ae682015-06-29 17:44:04 -0700276 gpr_slice slice;
277};
278
Craig Tiller45724b32015-09-22 10:42:19 -0700279static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700280shutdown_cleanup (grpc_exec_ctx * exec_ctx, void *arg, int iomgr_status_ignored)
Craig Tiller45724b32015-09-22 10:42:19 -0700281{
Craig Tillerff3ae682015-06-29 17:44:04 -0700282 struct shutdown_cleanup_args *a = arg;
Craig Tiller45724b32015-09-22 10:42:19 -0700283 gpr_slice_unref (a->slice);
284 gpr_free (a);
Craig Tillerff3ae682015-06-29 17:44:04 -0700285}
286
Craig Tiller45724b32015-09-22 10:42:19 -0700287static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700288send_shutdown (grpc_exec_ctx * exec_ctx, grpc_channel * channel, int send_goaway, int send_disconnect)
Craig Tiller45724b32015-09-22 10:42:19 -0700289{
Craig Tillerff3ae682015-06-29 17:44:04 -0700290 grpc_transport_op op;
291 struct shutdown_cleanup_args *sc;
292 grpc_channel_element *elem;
293
Craig Tiller45724b32015-09-22 10:42:19 -0700294 memset (&op, 0, sizeof (op));
Craig Tillerff3ae682015-06-29 17:44:04 -0700295 op.send_goaway = send_goaway;
Craig Tiller45724b32015-09-22 10:42:19 -0700296 sc = gpr_malloc (sizeof (*sc));
297 sc->slice = gpr_slice_from_copied_string ("Server shutdown");
Craig Tillerff3ae682015-06-29 17:44:04 -0700298 op.goaway_message = &sc->slice;
299 op.goaway_status = GRPC_STATUS_OK;
300 op.disconnect = send_disconnect;
Craig Tiller45724b32015-09-22 10:42:19 -0700301 grpc_closure_init (&sc->closure, shutdown_cleanup, sc);
Craig Tillerff3ae682015-06-29 17:44:04 -0700302 op.on_consumed = &sc->closure;
303
Craig Tiller45724b32015-09-22 10:42:19 -0700304 elem = grpc_channel_stack_element (grpc_channel_get_channel_stack (channel), 0);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700305 elem->filter->start_transport_op (exec_ctx, elem, &op);
Craig Tillerff3ae682015-06-29 17:44:04 -0700306}
307
Craig Tiller45724b32015-09-22 10:42:19 -0700308static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700309channel_broadcaster_shutdown (grpc_exec_ctx * exec_ctx, channel_broadcaster * cb, int send_goaway, int force_disconnect)
Craig Tiller45724b32015-09-22 10:42:19 -0700310{
Craig Tillerff3ae682015-06-29 17:44:04 -0700311 size_t i;
312
Craig Tiller45724b32015-09-22 10:42:19 -0700313 for (i = 0; i < cb->num_channels; i++)
314 {
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700315 send_shutdown (exec_ctx, cb->channels[i], send_goaway, force_disconnect);
316 GRPC_CHANNEL_INTERNAL_UNREF (exec_ctx, cb->channels[i], "broadcast");
Craig Tiller45724b32015-09-22 10:42:19 -0700317 }
318 gpr_free (cb->channels);
Craig Tillerff3ae682015-06-29 17:44:04 -0700319}
320
Craig Tiller729b35a2015-07-13 12:36:47 -0700321/*
322 * request_matcher
323 */
Craig Tillerff3ae682015-06-29 17:44:04 -0700324
Craig Tiller45724b32015-09-22 10:42:19 -0700325static void
326request_matcher_init (request_matcher * request_matcher, size_t entries)
327{
328 memset (request_matcher, 0, sizeof (*request_matcher));
329 request_matcher->requests = gpr_stack_lockfree_create (entries);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800330}
331
Craig Tiller45724b32015-09-22 10:42:19 -0700332static void
333request_matcher_destroy (request_matcher * request_matcher)
334{
335 GPR_ASSERT (gpr_stack_lockfree_pop (request_matcher->requests) == -1);
336 gpr_stack_lockfree_destroy (request_matcher->requests);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800337}
338
Craig Tiller45724b32015-09-22 10:42:19 -0700339static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700340kill_zombie (grpc_exec_ctx * exec_ctx, void *elem, int success)
Craig Tiller45724b32015-09-22 10:42:19 -0700341{
342 grpc_call_destroy (grpc_call_from_top_element (elem));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800343}
344
Craig Tiller45724b32015-09-22 10:42:19 -0700345static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700346request_matcher_zombify_all_pending_calls (grpc_exec_ctx * exec_ctx, request_matcher * request_matcher)
Craig Tiller45724b32015-09-22 10:42:19 -0700347{
348 while (request_matcher->pending_head)
349 {
350 call_data *calld = request_matcher->pending_head;
351 request_matcher->pending_head = calld->pending_next;
352 gpr_mu_lock (&calld->mu_state);
353 calld->state = ZOMBIED;
354 gpr_mu_unlock (&calld->mu_state);
355 grpc_closure_init (&calld->kill_zombie_closure, kill_zombie, grpc_call_stack_element (grpc_call_get_call_stack (calld->call), 0));
Craig Tiller8ad03752015-09-22 10:48:23 -0700356 grpc_exec_ctx_enqueue (exec_ctx, &calld->kill_zombie_closure, 1);
Craig Tiller45724b32015-09-22 10:42:19 -0700357 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800358}
359
Craig Tiller45724b32015-09-22 10:42:19 -0700360static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700361request_matcher_kill_requests (grpc_exec_ctx * exec_ctx, grpc_server * server, request_matcher * rm)
Craig Tiller45724b32015-09-22 10:42:19 -0700362{
Craig Tiller1191e212015-07-30 14:49:02 -0700363 int request_id;
Craig Tiller45724b32015-09-22 10:42:19 -0700364 while ((request_id = gpr_stack_lockfree_pop (rm->requests)) != -1)
365 {
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700366 fail_call (exec_ctx, server, &server->requested_calls[request_id]);
Craig Tiller45724b32015-09-22 10:42:19 -0700367 }
Craig Tiller1191e212015-07-30 14:49:02 -0700368}
369
Craig Tiller729b35a2015-07-13 12:36:47 -0700370/*
371 * server proper
372 */
373
Craig Tiller45724b32015-09-22 10:42:19 -0700374static void
375server_ref (grpc_server * server)
376{
377 gpr_ref (&server->internal_refcount);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800378}
379
Craig Tiller45724b32015-09-22 10:42:19 -0700380static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700381server_delete (grpc_exec_ctx * exec_ctx, grpc_server * server)
Craig Tiller45724b32015-09-22 10:42:19 -0700382{
Craig Tillerec3257c2015-02-12 15:59:43 -0800383 registered_method *rm;
Craig Tiller89504612015-04-27 11:48:46 -0700384 size_t i;
Craig Tiller45724b32015-09-22 10:42:19 -0700385 grpc_channel_args_destroy (server->channel_args);
386 gpr_mu_destroy (&server->mu_global);
387 gpr_mu_destroy (&server->mu_call);
388 gpr_free (server->channel_filters);
389 while ((rm = server->registered_methods) != NULL)
390 {
391 server->registered_methods = rm->next;
392 request_matcher_destroy (&rm->request_matcher);
393 gpr_free (rm->method);
394 gpr_free (rm->host);
395 gpr_free (rm);
396 }
397 for (i = 0; i < server->cq_count; i++)
398 {
399 GRPC_CQ_INTERNAL_UNREF (server->cqs[i], "server");
400 }
401 request_matcher_destroy (&server->unregistered_request_matcher);
402 gpr_stack_lockfree_destroy (server->request_freelist);
403 gpr_free (server->cqs);
404 gpr_free (server->pollsets);
405 gpr_free (server->shutdown_tags);
406 gpr_free (server->requested_calls);
407 gpr_free (server);
Craig Tilleree945e82015-05-26 16:15:34 -0700408}
409
Craig Tiller45724b32015-09-22 10:42:19 -0700410static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700411server_unref (grpc_exec_ctx * exec_ctx, grpc_server * server)
Craig Tiller45724b32015-09-22 10:42:19 -0700412{
413 if (gpr_unref (&server->internal_refcount))
414 {
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700415 server_delete (exec_ctx, server);
Craig Tiller45724b32015-09-22 10:42:19 -0700416 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800417}
418
Craig Tiller45724b32015-09-22 10:42:19 -0700419static int
420is_channel_orphaned (channel_data * chand)
421{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800422 return chand->next == chand;
423}
424
Craig Tiller45724b32015-09-22 10:42:19 -0700425static void
426orphan_channel (channel_data * chand)
427{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800428 chand->next->prev = chand->prev;
429 chand->prev->next = chand->next;
430 chand->next = chand->prev = chand;
431}
432
Craig Tiller45724b32015-09-22 10:42:19 -0700433static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700434finish_destroy_channel (grpc_exec_ctx * exec_ctx, void *cd, int success)
Craig Tiller45724b32015-09-22 10:42:19 -0700435{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800436 channel_data *chand = cd;
437 grpc_server *server = chand->server;
Craig Tiller45724b32015-09-22 10:42:19 -0700438 gpr_log (GPR_DEBUG, "finish_destroy_channel: %p", chand->channel);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700439 GRPC_CHANNEL_INTERNAL_UNREF (exec_ctx, chand->channel, "server");
440 server_unref (exec_ctx, server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800441}
442
Craig Tiller45724b32015-09-22 10:42:19 -0700443static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700444destroy_channel (grpc_exec_ctx * exec_ctx, channel_data * chand)
Craig Tiller45724b32015-09-22 10:42:19 -0700445{
446 if (is_channel_orphaned (chand))
447 return;
448 GPR_ASSERT (chand->server != NULL);
449 orphan_channel (chand);
450 server_ref (chand->server);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700451 maybe_finish_shutdown (exec_ctx, chand->server);
David Garcia Quintas284488b2015-05-28 16:27:39 -0700452 chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
453 chand->finish_destroy_channel_closure.cb_arg = chand;
Craig Tiller8ad03752015-09-22 10:48:23 -0700454 grpc_exec_ctx_enqueue (exec_ctx, &chand->finish_destroy_channel_closure, 1);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800455}
456
Craig Tiller45724b32015-09-22 10:42:19 -0700457static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700458finish_start_new_rpc (grpc_exec_ctx * exec_ctx, grpc_server * server, grpc_call_element * elem, request_matcher * request_matcher)
Craig Tiller45724b32015-09-22 10:42:19 -0700459{
Craig Tiller04cc8be2015-02-10 16:11:22 -0800460 call_data *calld = elem->call_data;
Craig Tiller6a006ce2015-07-13 16:25:40 -0700461 int request_id;
462
Craig Tiller45724b32015-09-22 10:42:19 -0700463 if (gpr_atm_acq_load (&server->shutdown_flag))
464 {
465 gpr_mu_lock (&calld->mu_state);
466 calld->state = ZOMBIED;
467 gpr_mu_unlock (&calld->mu_state);
468 grpc_closure_init (&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller8ad03752015-09-22 10:48:23 -0700469 grpc_exec_ctx_enqueue (exec_ctx, &calld->kill_zombie_closure, 1);
Craig Tiller45724b32015-09-22 10:42:19 -0700470 return;
Craig Tiller729b35a2015-07-13 12:36:47 -0700471 }
Craig Tiller45724b32015-09-22 10:42:19 -0700472
473 request_id = gpr_stack_lockfree_pop (request_matcher->requests);
474 if (request_id == -1)
475 {
476 gpr_mu_lock (&server->mu_call);
477 gpr_mu_lock (&calld->mu_state);
478 calld->state = PENDING;
479 gpr_mu_unlock (&calld->mu_state);
480 if (request_matcher->pending_head == NULL)
481 {
482 request_matcher->pending_tail = request_matcher->pending_head = calld;
483 }
484 else
485 {
486 request_matcher->pending_tail->pending_next = calld;
487 request_matcher->pending_tail = calld;
488 }
489 calld->pending_next = NULL;
490 gpr_mu_unlock (&server->mu_call);
491 }
492 else
493 {
494 gpr_mu_lock (&calld->mu_state);
495 calld->state = ACTIVATED;
496 gpr_mu_unlock (&calld->mu_state);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700497 begin_call (exec_ctx, server, calld, &server->requested_calls[request_id]);
Craig Tiller45724b32015-09-22 10:42:19 -0700498 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800499}
500
Craig Tiller45724b32015-09-22 10:42:19 -0700501static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700502start_new_rpc (grpc_exec_ctx * exec_ctx, grpc_call_element * elem)
Craig Tiller45724b32015-09-22 10:42:19 -0700503{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800504 channel_data *chand = elem->channel_data;
505 call_data *calld = elem->call_data;
506 grpc_server *server = chand->server;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800507 gpr_uint32 i;
508 gpr_uint32 hash;
509 channel_registered_method *rm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800510
Craig Tiller45724b32015-09-22 10:42:19 -0700511 if (chand->registered_methods && calld->path && calld->host)
512 {
513 /* TODO(ctiller): unify these two searches */
514 /* check for an exact match with host */
515 hash = GRPC_MDSTR_KV_HASH (calld->host->hash, calld->path->hash);
516 for (i = 0; i <= chand->registered_method_max_probes; i++)
517 {
518 rm = &chand->registered_methods[(hash + i) % chand->registered_method_slots];
519 if (!rm)
520 break;
521 if (rm->host != calld->host)
522 continue;
523 if (rm->method != calld->path)
524 continue;
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700525 finish_start_new_rpc (exec_ctx, server, elem, &rm->server_registered_method->request_matcher);
Craig Tiller45724b32015-09-22 10:42:19 -0700526 return;
527 }
528 /* check for a wildcard method definition (no host set) */
529 hash = GRPC_MDSTR_KV_HASH (0, calld->path->hash);
530 for (i = 0; i <= chand->registered_method_max_probes; i++)
531 {
532 rm = &chand->registered_methods[(hash + i) % chand->registered_method_slots];
533 if (!rm)
534 break;
535 if (rm->host != NULL)
536 continue;
537 if (rm->method != calld->path)
538 continue;
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700539 finish_start_new_rpc (exec_ctx, server, elem, &rm->server_registered_method->request_matcher);
Craig Tiller45724b32015-09-22 10:42:19 -0700540 return;
541 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800542 }
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700543 finish_start_new_rpc (exec_ctx, server, elem, &server->unregistered_request_matcher);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800544}
545
Craig Tiller45724b32015-09-22 10:42:19 -0700546static int
547num_listeners (grpc_server * server)
548{
Craig Tilleree945e82015-05-26 16:15:34 -0700549 listener *l;
550 int n = 0;
Craig Tiller45724b32015-09-22 10:42:19 -0700551 for (l = server->listeners; l; l = l->next)
552 {
553 n++;
554 }
Craig Tilleree945e82015-05-26 16:15:34 -0700555 return n;
556}
557
Craig Tiller45724b32015-09-22 10:42:19 -0700558static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700559done_shutdown_event (grpc_exec_ctx * exec_ctx, void *server, grpc_cq_completion * completion)
Craig Tiller45724b32015-09-22 10:42:19 -0700560{
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700561 server_unref (exec_ctx, server);
Craig Tiller97fc6a32015-07-08 15:31:35 -0700562}
563
Craig Tiller45724b32015-09-22 10:42:19 -0700564static int
565num_channels (grpc_server * server)
566{
Craig Tillerab54f792015-07-08 08:34:20 -0700567 channel_data *chand;
568 int n = 0;
Craig Tiller45724b32015-09-22 10:42:19 -0700569 for (chand = server->root_channel_data.next; chand != &server->root_channel_data; chand = chand->next)
570 {
571 n++;
572 }
Craig Tillerab54f792015-07-08 08:34:20 -0700573 return n;
574}
575
Craig Tiller45724b32015-09-22 10:42:19 -0700576static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700577kill_pending_work_locked (grpc_exec_ctx * exec_ctx, grpc_server * server)
Craig Tiller45724b32015-09-22 10:42:19 -0700578{
Craig Tiller1191e212015-07-30 14:49:02 -0700579 registered_method *rm;
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700580 request_matcher_kill_requests (exec_ctx, server, &server->unregistered_request_matcher);
581 request_matcher_zombify_all_pending_calls (exec_ctx, &server->unregistered_request_matcher);
Craig Tiller45724b32015-09-22 10:42:19 -0700582 for (rm = server->registered_methods; rm; rm = rm->next)
583 {
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700584 request_matcher_kill_requests (exec_ctx, server, &rm->request_matcher);
585 request_matcher_zombify_all_pending_calls (exec_ctx, &rm->request_matcher);
Craig Tillerab54f792015-07-08 08:34:20 -0700586 }
Craig Tillerdc627722015-05-26 15:27:02 -0700587}
588
Craig Tiller45724b32015-09-22 10:42:19 -0700589static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700590maybe_finish_shutdown (grpc_exec_ctx * exec_ctx, grpc_server * server)
Craig Tiller45724b32015-09-22 10:42:19 -0700591{
592 size_t i;
593 if (!gpr_atm_acq_load (&server->shutdown_flag) || server->shutdown_published)
594 {
595 return;
596 }
597
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700598 kill_pending_work_locked (exec_ctx, server);
Craig Tiller45724b32015-09-22 10:42:19 -0700599
600 if (server->root_channel_data.next != &server->root_channel_data || server->listeners_destroyed < num_listeners (server))
601 {
602 if (gpr_time_cmp (gpr_time_sub (gpr_now (GPR_CLOCK_REALTIME), server->last_shutdown_message_time), gpr_time_from_seconds (1, GPR_TIMESPAN)) >= 0)
603 {
604 server->last_shutdown_message_time = gpr_now (GPR_CLOCK_REALTIME);
605 gpr_log (GPR_DEBUG, "Waiting for %d channels and %d/%d listeners to be destroyed" " before shutting down server", num_channels (server), num_listeners (server) - server->listeners_destroyed, num_listeners (server));
606 }
607 return;
608 }
609 server->shutdown_published = 1;
610 for (i = 0; i < server->num_shutdown_tags; i++)
611 {
612 server_ref (server);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700613 grpc_cq_end_op (exec_ctx, server->shutdown_tags[i].cq, server->shutdown_tags[i].tag, 1, done_shutdown_event, server, &server->shutdown_tags[i].completion);
Craig Tiller45724b32015-09-22 10:42:19 -0700614 }
615}
616
617static grpc_mdelem *
618server_filter (void *user_data, grpc_mdelem * md)
619{
Craig Tiller6902ad22015-04-16 08:01:49 -0700620 grpc_call_element *elem = user_data;
Craig Tillercce17ac2015-01-20 09:29:28 -0800621 channel_data *chand = elem->channel_data;
622 call_data *calld = elem->call_data;
Craig Tiller45724b32015-09-22 10:42:19 -0700623 if (md->key == chand->path_key)
624 {
625 calld->path = GRPC_MDSTR_REF (md->value);
626 return NULL;
627 }
628 else if (md->key == chand->authority_key)
629 {
630 calld->host = GRPC_MDSTR_REF (md->value);
631 return NULL;
632 }
Craig Tiller6902ad22015-04-16 08:01:49 -0700633 return md;
634}
635
Craig Tiller45724b32015-09-22 10:42:19 -0700636static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700637server_on_recv (grpc_exec_ctx * exec_ctx, void *ptr, int success)
Craig Tiller45724b32015-09-22 10:42:19 -0700638{
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700639 grpc_call_element *elem = ptr;
Craig Tiller6902ad22015-04-16 08:01:49 -0700640 call_data *calld = elem->call_data;
Craig Tiller94329d02015-07-23 09:52:11 -0700641 gpr_timespec op_deadline;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700642
Craig Tiller45724b32015-09-22 10:42:19 -0700643 if (success && !calld->got_initial_metadata)
644 {
645 size_t i;
646 size_t nops = calld->recv_ops->nops;
647 grpc_stream_op *ops = calld->recv_ops->ops;
648 for (i = 0; i < nops; i++)
649 {
650 grpc_stream_op *op = &ops[i];
651 if (op->type != GRPC_OP_METADATA)
652 continue;
653 grpc_metadata_batch_filter (&op->data.metadata, server_filter, elem);
654 op_deadline = op->data.metadata.deadline;
655 if (0 != gpr_time_cmp (op_deadline, gpr_inf_future (op_deadline.clock_type)))
656 {
657 calld->deadline = op->data.metadata.deadline;
658 }
659 if (calld->host && calld->path)
660 {
661 calld->got_initial_metadata = 1;
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700662 start_new_rpc (exec_ctx, elem);
Craig Tiller45724b32015-09-22 10:42:19 -0700663 }
664 break;
665 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700666 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700667
Craig Tiller45724b32015-09-22 10:42:19 -0700668 switch (*calld->recv_state)
669 {
Craig Tiller06aeea72015-04-23 10:54:45 -0700670 case GRPC_STREAM_OPEN:
671 break;
672 case GRPC_STREAM_SEND_CLOSED:
673 break;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700674 case GRPC_STREAM_RECV_CLOSED:
Craig Tiller45724b32015-09-22 10:42:19 -0700675 gpr_mu_lock (&calld->mu_state);
676 if (calld->state == NOT_STARTED)
677 {
678 calld->state = ZOMBIED;
679 gpr_mu_unlock (&calld->mu_state);
680 grpc_closure_init (&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller8ad03752015-09-22 10:48:23 -0700681 grpc_exec_ctx_enqueue (exec_ctx, &calld->kill_zombie_closure, 1);
Craig Tiller45724b32015-09-22 10:42:19 -0700682 }
683 else
684 {
685 gpr_mu_unlock (&calld->mu_state);
686 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800687 break;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700688 case GRPC_STREAM_CLOSED:
Craig Tiller45724b32015-09-22 10:42:19 -0700689 gpr_mu_lock (&calld->mu_state);
690 if (calld->state == NOT_STARTED)
691 {
692 calld->state = ZOMBIED;
693 gpr_mu_unlock (&calld->mu_state);
694 grpc_closure_init (&calld->kill_zombie_closure, kill_zombie, elem);
Craig Tiller8ad03752015-09-22 10:48:23 -0700695 grpc_exec_ctx_enqueue (exec_ctx, &calld->kill_zombie_closure, 1);
Craig Tiller45724b32015-09-22 10:42:19 -0700696 }
697 else if (calld->state == PENDING)
698 {
699 calld->state = ZOMBIED;
700 gpr_mu_unlock (&calld->mu_state);
701 /* zombied call will be destroyed when it's removed from the pending
702 queue... later */
703 }
704 else
705 {
706 gpr_mu_unlock (&calld->mu_state);
707 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800708 break;
Craig Tiller45724b32015-09-22 10:42:19 -0700709 }
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700710
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700711 calld->on_done_recv->cb (exec_ctx, calld->on_done_recv->cb_arg, success);
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700712}
713
Craig Tiller45724b32015-09-22 10:42:19 -0700714static void
715server_mutate_op (grpc_call_element * elem, grpc_transport_stream_op * op)
716{
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700717 call_data *calld = elem->call_data;
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700718
Craig Tiller45724b32015-09-22 10:42:19 -0700719 if (op->recv_ops)
720 {
721 /* substitute our callback for the higher callback */
722 calld->recv_ops = op->recv_ops;
723 calld->recv_state = op->recv_state;
724 calld->on_done_recv = op->on_done_recv;
725 op->on_done_recv = &calld->server_on_recv;
726 }
Craig Tiller50d9db52015-04-23 10:52:14 -0700727}
Craig Tillerbe18b8d2015-04-22 14:00:47 -0700728
Craig Tiller45724b32015-09-22 10:42:19 -0700729static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700730server_start_transport_stream_op (grpc_exec_ctx * exec_ctx, grpc_call_element * elem, grpc_transport_stream_op * op)
Craig Tiller45724b32015-09-22 10:42:19 -0700731{
732 GRPC_CALL_LOG_OP (GPR_INFO, elem, op);
733 server_mutate_op (elem, op);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700734 grpc_call_next_op (exec_ctx, elem, op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800735}
736
Craig Tiller45724b32015-09-22 10:42:19 -0700737static void
738accept_stream (void *cd, grpc_transport * transport, const void *transport_server_data)
739{
Craig Tillere039f032015-06-25 12:54:23 -0700740 channel_data *chand = cd;
741 /* create a call */
Craig Tiller45724b32015-09-22 10:42:19 -0700742 grpc_call_create (chand->channel, NULL, 0, NULL, transport_server_data, NULL, 0, gpr_inf_future (GPR_CLOCK_MONOTONIC));
Craig Tillere039f032015-06-25 12:54:23 -0700743}
744
Craig Tiller45724b32015-09-22 10:42:19 -0700745static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700746channel_connectivity_changed (grpc_exec_ctx * exec_ctx, void *cd, int iomgr_status_ignored)
Craig Tiller45724b32015-09-22 10:42:19 -0700747{
Craig Tillere039f032015-06-25 12:54:23 -0700748 channel_data *chand = cd;
749 grpc_server *server = chand->server;
Craig Tiller45724b32015-09-22 10:42:19 -0700750 if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE)
751 {
752 grpc_transport_op op;
753 memset (&op, 0, sizeof (op));
754 op.on_connectivity_state_change = &chand->channel_connectivity_changed, op.connectivity_state = &chand->connectivity_state;
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700755 grpc_channel_next_op (grpc_channel_stack_element (grpc_channel_get_channel_stack (exec_ctx, chand->channel), 0), &op);
Craig Tiller45724b32015-09-22 10:42:19 -0700756 }
757 else
758 {
759 gpr_mu_lock (&server->mu_global);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700760 destroy_channel (exec_ctx, chand);
Craig Tiller45724b32015-09-22 10:42:19 -0700761 gpr_mu_unlock (&server->mu_global);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700762 GRPC_CHANNEL_INTERNAL_UNREF (exec_ctx, chand->channel, "connectivity");
Craig Tiller45724b32015-09-22 10:42:19 -0700763 }
Craig Tillere039f032015-06-25 12:54:23 -0700764}
765
Craig Tiller45724b32015-09-22 10:42:19 -0700766static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700767init_call_elem (grpc_exec_ctx * exec_ctx, grpc_call_element * elem, const void *server_transport_data, grpc_transport_stream_op * initial_op)
Craig Tiller45724b32015-09-22 10:42:19 -0700768{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800769 call_data *calld = elem->call_data;
770 channel_data *chand = elem->channel_data;
Craig Tiller45724b32015-09-22 10:42:19 -0700771 memset (calld, 0, sizeof (call_data));
772 calld->deadline = gpr_inf_future (GPR_CLOCK_REALTIME);
773 calld->call = grpc_call_from_top_element (elem);
774 gpr_mu_init (&calld->mu_state);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800775
Craig Tiller45724b32015-09-22 10:42:19 -0700776 grpc_closure_init (&calld->server_on_recv, server_on_recv, elem);
Craig Tiller1e6facb2015-06-11 22:47:11 -0700777
Craig Tiller45724b32015-09-22 10:42:19 -0700778 server_ref (chand->server);
Craig Tiller50d9db52015-04-23 10:52:14 -0700779
Craig Tiller45724b32015-09-22 10:42:19 -0700780 if (initial_op)
781 server_mutate_op (elem, initial_op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800782}
783
Craig Tiller45724b32015-09-22 10:42:19 -0700784static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700785destroy_call_elem (grpc_exec_ctx * exec_ctx, grpc_call_element * elem)
Craig Tiller45724b32015-09-22 10:42:19 -0700786{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800787 channel_data *chand = elem->channel_data;
Craig Tillerdb7db992015-01-29 11:19:01 -0800788 call_data *calld = elem->call_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800789
Craig Tiller45724b32015-09-22 10:42:19 -0700790 GPR_ASSERT (calld->state != PENDING);
Craig Tiller092d8d12015-07-04 22:35:00 -0700791
Craig Tiller45724b32015-09-22 10:42:19 -0700792 if (calld->host)
793 {
794 GRPC_MDSTR_UNREF (calld->host);
795 }
796 if (calld->path)
797 {
798 GRPC_MDSTR_UNREF (calld->path);
799 }
Craig Tiller4df31a62015-01-30 09:44:31 -0800800
Craig Tiller45724b32015-09-22 10:42:19 -0700801 gpr_mu_destroy (&calld->mu_state);
Craig Tiller76d2c3b2015-07-07 11:46:01 -0700802
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700803 server_unref (exec_ctx, chand->server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800804}
805
Craig Tiller45724b32015-09-22 10:42:19 -0700806static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700807init_channel_elem (grpc_exec_ctx * exec_ctx, grpc_channel_element * elem, grpc_channel * master, const grpc_channel_args * args, grpc_mdctx * metadata_context, int is_first, int is_last)
Craig Tiller45724b32015-09-22 10:42:19 -0700808{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800809 channel_data *chand = elem->channel_data;
Craig Tiller45724b32015-09-22 10:42:19 -0700810 GPR_ASSERT (is_first);
811 GPR_ASSERT (!is_last);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800812 chand->server = NULL;
813 chand->channel = NULL;
Craig Tiller45724b32015-09-22 10:42:19 -0700814 chand->path_key = grpc_mdstr_from_string (metadata_context, ":path", 0);
815 chand->authority_key = grpc_mdstr_from_string (metadata_context, ":authority", 0);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800816 chand->next = chand->prev = chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800817 chand->registered_methods = NULL;
Craig Tillere039f032015-06-25 12:54:23 -0700818 chand->connectivity_state = GRPC_CHANNEL_IDLE;
Craig Tiller45724b32015-09-22 10:42:19 -0700819 grpc_closure_init (&chand->channel_connectivity_changed, channel_connectivity_changed, chand);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800820}
821
Craig Tiller45724b32015-09-22 10:42:19 -0700822static void
Craig Tiller1be70cc2015-09-22 10:45:28 -0700823destroy_channel_elem (grpc_exec_ctx * exec_ctx, grpc_channel_element * elem)
Craig Tiller45724b32015-09-22 10:42:19 -0700824{
Craig Tillerec3257c2015-02-12 15:59:43 -0800825 size_t i;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800826 channel_data *chand = elem->channel_data;
Craig Tiller45724b32015-09-22 10:42:19 -0700827 if (chand->registered_methods)
828 {
829 for (i = 0; i < chand->registered_method_slots; i++)
830 {
831 if (chand->registered_methods[i].method)
832 {
833 GRPC_MDSTR_UNREF (chand->registered_methods[i].method);
834 }
835 if (chand->registered_methods[i].host)
836 {
837 GRPC_MDSTR_UNREF (chand->registered_methods[i].host);
838 }
839 }
840 gpr_free (chand->registered_methods);
Craig Tillerec3257c2015-02-12 15:59:43 -0800841 }
Craig Tiller45724b32015-09-22 10:42:19 -0700842 if (chand->server)
843 {
844 gpr_mu_lock (&chand->server->mu_global);
845 chand->next->prev = chand->prev;
846 chand->prev->next = chand->next;
847 chand->next = chand->prev = chand;
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700848 maybe_finish_shutdown (exec_ctx, chand->server);
Craig Tiller45724b32015-09-22 10:42:19 -0700849 gpr_mu_unlock (&chand->server->mu_global);
850 GRPC_MDSTR_UNREF (chand->path_key);
851 GRPC_MDSTR_UNREF (chand->authority_key);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -0700852 server_unref (exec_ctx, chand->server);
Craig Tiller45724b32015-09-22 10:42:19 -0700853 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800854}
855
856static const grpc_channel_filter server_surface_filter = {
Craig Tiller45724b32015-09-22 10:42:19 -0700857 server_start_transport_stream_op,
858 grpc_channel_next_op,
859 sizeof (call_data),
860 init_call_elem,
861 destroy_call_elem,
862 sizeof (channel_data),
863 init_channel_elem,
864 destroy_channel_elem,
865 grpc_call_next_get_peer,
866 "server",
Craig Tiller9f28ac22015-01-27 17:01:29 -0800867};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800868
Craig Tiller45724b32015-09-22 10:42:19 -0700869void
870grpc_server_register_completion_queue (grpc_server * server, grpc_completion_queue * cq, void *reserved)
871{
Craig Tiller20bc56d2015-02-12 09:02:56 -0800872 size_t i, n;
Craig Tiller45724b32015-09-22 10:42:19 -0700873 GPR_ASSERT (!reserved);
874 for (i = 0; i < server->cq_count; i++)
875 {
876 if (server->cqs[i] == cq)
877 return;
878 }
879 GRPC_CQ_INTERNAL_REF (cq, "server");
880 grpc_cq_mark_server_cq (cq);
Craig Tiller20bc56d2015-02-12 09:02:56 -0800881 n = server->cq_count++;
Craig Tiller45724b32015-09-22 10:42:19 -0700882 server->cqs = gpr_realloc (server->cqs, server->cq_count * sizeof (grpc_completion_queue *));
Craig Tiller20bc56d2015-02-12 09:02:56 -0800883 server->cqs[n] = cq;
884}
885
Craig Tiller45724b32015-09-22 10:42:19 -0700886grpc_server *
887grpc_server_create_from_filters (const grpc_channel_filter ** filters, size_t filter_count, const grpc_channel_args * args)
888{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800889 size_t i;
Alistair Veitch9d48ebf2015-06-01 10:01:03 -0700890 /* TODO(census): restore this once we finalize census filter etc.
891 int census_enabled = grpc_channel_args_is_census_enabled(args); */
892 int census_enabled = 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800893
Craig Tiller45724b32015-09-22 10:42:19 -0700894 grpc_server *server = gpr_malloc (sizeof (grpc_server));
Craig Tiller60fd3612015-03-05 16:24:22 -0800895
Craig Tiller45724b32015-09-22 10:42:19 -0700896 GPR_ASSERT (grpc_is_initialized () && "call grpc_init()");
Craig Tiller60fd3612015-03-05 16:24:22 -0800897
Craig Tiller45724b32015-09-22 10:42:19 -0700898 memset (server, 0, sizeof (grpc_server));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800899
Craig Tiller45724b32015-09-22 10:42:19 -0700900 gpr_mu_init (&server->mu_global);
901 gpr_mu_init (&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800902
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800903 /* decremented by grpc_server_destroy */
Craig Tiller45724b32015-09-22 10:42:19 -0700904 gpr_ref_init (&server->internal_refcount, 1);
905 server->root_channel_data.next = server->root_channel_data.prev = &server->root_channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800906
Craig Tiller6a006ce2015-07-13 16:25:40 -0700907 /* TODO(ctiller): expose a channel_arg for this */
908 server->max_requested_calls = 32768;
Craig Tiller45724b32015-09-22 10:42:19 -0700909 server->request_freelist = gpr_stack_lockfree_create (server->max_requested_calls);
910 for (i = 0; i < (size_t) server->max_requested_calls; i++)
911 {
912 gpr_stack_lockfree_push (server->request_freelist, (int) i);
913 }
914 request_matcher_init (&server->unregistered_request_matcher, server->max_requested_calls);
915 server->requested_calls = gpr_malloc (server->max_requested_calls * sizeof (*server->requested_calls));
Craig Tiller729b35a2015-07-13 12:36:47 -0700916
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800917 /* Server filter stack is:
918
919 server_surface_filter - for making surface API calls
920 grpc_server_census_filter (optional) - for stats collection and tracing
921 {passed in filter stack}
922 grpc_connected_channel_filter - for interfacing with transports */
Craig Tiller32ca48c2015-09-10 11:47:15 -0700923 server->channel_filter_count = filter_count + 1u + (census_enabled ? 1u : 0u);
Craig Tiller45724b32015-09-22 10:42:19 -0700924 server->channel_filters = gpr_malloc (server->channel_filter_count * sizeof (grpc_channel_filter *));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800925 server->channel_filters[0] = &server_surface_filter;
Craig Tiller45724b32015-09-22 10:42:19 -0700926 if (census_enabled)
927 {
928 server->channel_filters[1] = &grpc_server_census_filter;
929 }
930 for (i = 0; i < filter_count; i++)
931 {
932 server->channel_filters[i + 1u + (census_enabled ? 1u : 0u)] = filters[i];
933 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800934
Craig Tiller45724b32015-09-22 10:42:19 -0700935 server->channel_args = grpc_channel_args_copy (args);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800936
937 return server;
938}
939
Craig Tiller45724b32015-09-22 10:42:19 -0700940static int
941streq (const char *a, const char *b)
942{
943 if (a == NULL && b == NULL)
944 return 1;
945 if (a == NULL)
946 return 0;
947 if (b == NULL)
948 return 0;
949 return 0 == strcmp (a, b);
Craig Tiller24be0f72015-02-10 14:04:22 -0800950}
951
Craig Tiller45724b32015-09-22 10:42:19 -0700952void *
953grpc_server_register_method (grpc_server * server, const char *method, const char *host)
954{
Craig Tiller24be0f72015-02-10 14:04:22 -0800955 registered_method *m;
Craig Tiller45724b32015-09-22 10:42:19 -0700956 if (!method)
957 {
958 gpr_log (GPR_ERROR, "grpc_server_register_method method string cannot be NULL");
Craig Tiller24be0f72015-02-10 14:04:22 -0800959 return NULL;
960 }
Craig Tiller45724b32015-09-22 10:42:19 -0700961 for (m = server->registered_methods; m; m = m->next)
962 {
963 if (streq (m->method, method) && streq (m->host, host))
964 {
965 gpr_log (GPR_ERROR, "duplicate registration for %s@%s", method, host ? host : "*");
966 return NULL;
967 }
968 }
969 m = gpr_malloc (sizeof (registered_method));
970 memset (m, 0, sizeof (*m));
971 request_matcher_init (&m->request_matcher, server->max_requested_calls);
972 m->method = gpr_strdup (method);
973 m->host = gpr_strdup (host);
Craig Tiller24be0f72015-02-10 14:04:22 -0800974 m->next = server->registered_methods;
975 server->registered_methods = m;
976 return m;
977}
978
Craig Tiller45724b32015-09-22 10:42:19 -0700979void
980grpc_server_start (grpc_server * server)
981{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800982 listener *l;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800983 size_t i;
Craig Tillerf5768a62015-09-22 10:54:34 -0700984 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller20bc56d2015-02-12 09:02:56 -0800985
Craig Tiller45724b32015-09-22 10:42:19 -0700986 server->pollsets = gpr_malloc (sizeof (grpc_pollset *) * server->cq_count);
987 for (i = 0; i < server->cq_count; i++)
988 {
989 server->pollsets[i] = grpc_cq_pollset (server->cqs[i]);
990 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800991
Craig Tiller45724b32015-09-22 10:42:19 -0700992 for (l = server->listeners; l; l = l->next)
993 {
994 l->start (server, l->arg, server->pollsets, server->cq_count, &closure_list);
995 }
Craig Tillerdfff1b82015-09-21 14:39:57 -0700996
Craig Tiller098047b2015-09-22 10:53:14 -0700997 grpc_exec_ctx_finish (&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800998}
999
Craig Tiller45724b32015-09-22 10:42:19 -07001000void
Craig Tiller1be70cc2015-09-22 10:45:28 -07001001grpc_server_setup_transport (grpc_exec_ctx * exec_ctx, grpc_server * s, grpc_transport * transport, grpc_channel_filter const **extra_filters, size_t num_extra_filters, grpc_mdctx * mdctx, const grpc_channel_args * args)
Craig Tiller45724b32015-09-22 10:42:19 -07001002{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001003 size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
Craig Tiller45724b32015-09-22 10:42:19 -07001004 grpc_channel_filter const **filters = gpr_malloc (sizeof (grpc_channel_filter *) * num_filters);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001005 size_t i;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001006 size_t num_registered_methods;
1007 size_t alloc;
1008 registered_method *rm;
1009 channel_registered_method *crm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001010 grpc_channel *channel;
1011 channel_data *chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001012 grpc_mdstr *host;
1013 grpc_mdstr *method;
1014 gpr_uint32 hash;
Craig Tillerf96dfc32015-09-10 14:43:18 -07001015 size_t slots;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001016 gpr_uint32 probes;
1017 gpr_uint32 max_probes = 0;
Craig Tillere039f032015-06-25 12:54:23 -07001018 grpc_transport_op op;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001019
Craig Tiller45724b32015-09-22 10:42:19 -07001020 for (i = 0; i < s->channel_filter_count; i++)
1021 {
1022 filters[i] = s->channel_filters[i];
1023 }
1024 for (; i < s->channel_filter_count + num_extra_filters; i++)
1025 {
1026 filters[i] = extra_filters[i - s->channel_filter_count];
1027 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001028 filters[i] = &grpc_connected_channel_filter;
1029
Craig Tiller45724b32015-09-22 10:42:19 -07001030 for (i = 0; i < s->cq_count; i++)
1031 {
1032 memset (&op, 0, sizeof (op));
1033 op.bind_pollset = grpc_cq_pollset (s->cqs[i]);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001034 grpc_transport_perform_op (exec_ctx, transport, &op);
Craig Tiller45724b32015-09-22 10:42:19 -07001035 }
ctillerd79b4862014-12-17 16:36:59 -08001036
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001037 channel = grpc_channel_create_from_filters (exec_ctx, NULL, filters, num_filters, args, mdctx, 0);
Craig Tiller45724b32015-09-22 10:42:19 -07001038 chand = (channel_data *) grpc_channel_stack_element (grpc_channel_get_channel_stack (channel), 0)->channel_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001039 chand->server = s;
Craig Tiller45724b32015-09-22 10:42:19 -07001040 server_ref (s);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001041 chand->channel = channel;
1042
Craig Tiller04cc8be2015-02-10 16:11:22 -08001043 num_registered_methods = 0;
Craig Tiller45724b32015-09-22 10:42:19 -07001044 for (rm = s->registered_methods; rm; rm = rm->next)
1045 {
1046 num_registered_methods++;
1047 }
Craig Tiller04cc8be2015-02-10 16:11:22 -08001048 /* build a lookup table phrased in terms of mdstr's in this channels context
1049 to quickly find registered methods */
Craig Tiller45724b32015-09-22 10:42:19 -07001050 if (num_registered_methods > 0)
1051 {
1052 slots = 2 * num_registered_methods;
1053 alloc = sizeof (channel_registered_method) * slots;
1054 chand->registered_methods = gpr_malloc (alloc);
1055 memset (chand->registered_methods, 0, alloc);
1056 for (rm = s->registered_methods; rm; rm = rm->next)
1057 {
1058 host = rm->host ? grpc_mdstr_from_string (mdctx, rm->host, 0) : NULL;
1059 method = grpc_mdstr_from_string (mdctx, rm->method, 0);
1060 hash = GRPC_MDSTR_KV_HASH (host ? host->hash : 0, method->hash);
1061 for (probes = 0; chand->registered_methods[(hash + probes) % slots].server_registered_method != NULL; probes++)
1062 ;
1063 if (probes > max_probes)
1064 max_probes = probes;
1065 crm = &chand->registered_methods[(hash + probes) % slots];
1066 crm->server_registered_method = rm;
1067 crm->host = host;
1068 crm->method = method;
1069 }
1070 GPR_ASSERT (slots <= GPR_UINT32_MAX);
1071 chand->registered_method_slots = (gpr_uint32) slots;
1072 chand->registered_method_max_probes = max_probes;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001073 }
Craig Tiller04cc8be2015-02-10 16:11:22 -08001074
Craig Tiller45724b32015-09-22 10:42:19 -07001075 grpc_connected_channel_bind_transport (grpc_channel_get_channel_stack (channel), transport);
Craig Tiller7bd5ab12015-02-17 22:29:04 -08001076
Craig Tiller45724b32015-09-22 10:42:19 -07001077 gpr_mu_lock (&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001078 chand->next = &s->root_channel_data;
1079 chand->prev = chand->next->prev;
1080 chand->next->prev = chand->prev->next = chand;
Craig Tiller45724b32015-09-22 10:42:19 -07001081 gpr_mu_unlock (&s->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001082
Craig Tiller45724b32015-09-22 10:42:19 -07001083 gpr_free (filters);
Craig Tiller4b804102015-06-26 16:16:12 -07001084
Craig Tiller45724b32015-09-22 10:42:19 -07001085 GRPC_CHANNEL_INTERNAL_REF (channel, "connectivity");
1086 memset (&op, 0, sizeof (op));
Craig Tiller4b804102015-06-26 16:16:12 -07001087 op.set_accept_stream = accept_stream;
1088 op.set_accept_stream_user_data = chand;
1089 op.on_connectivity_state_change = &chand->channel_connectivity_changed;
1090 op.connectivity_state = &chand->connectivity_state;
Craig Tiller45724b32015-09-22 10:42:19 -07001091 op.disconnect = gpr_atm_acq_load (&s->shutdown_flag) != 0;
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001092 grpc_transport_perform_op (exec_ctx, transport, &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001093}
1094
Craig Tiller45724b32015-09-22 10:42:19 -07001095void
Craig Tiller1be70cc2015-09-22 10:45:28 -07001096done_published_shutdown (grpc_exec_ctx * exec_ctx, void *done_arg, grpc_cq_completion * storage)
Craig Tiller45724b32015-09-22 10:42:19 -07001097{
1098 (void) done_arg;
1099 gpr_free (storage);
murgatroid9900a3dab2015-08-19 11:15:38 -07001100}
1101
Craig Tiller45724b32015-09-22 10:42:19 -07001102static void
Craig Tiller1be70cc2015-09-22 10:45:28 -07001103listener_destroy_done (grpc_exec_ctx * exec_ctx, void *s, int success)
Craig Tiller45724b32015-09-22 10:42:19 -07001104{
Craig Tillerdfff1b82015-09-21 14:39:57 -07001105 grpc_server *server = s;
Craig Tiller45724b32015-09-22 10:42:19 -07001106 gpr_mu_lock (&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001107 server->listeners_destroyed++;
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001108 maybe_finish_shutdown (exec_ctx, server);
Craig Tiller45724b32015-09-22 10:42:19 -07001109 gpr_mu_unlock (&server->mu_global);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001110}
1111
Craig Tiller45724b32015-09-22 10:42:19 -07001112void
1113grpc_server_shutdown_and_notify (grpc_server * server, grpc_completion_queue * cq, void *tag)
1114{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001115 listener *l;
Craig Tillerbce999f2015-05-27 09:55:51 -07001116 shutdown_tag *sdt;
Craig Tillerff3ae682015-06-29 17:44:04 -07001117 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001118 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001119
Craig Tiller45724b32015-09-22 10:42:19 -07001120 GRPC_SERVER_LOG_SHUTDOWN (GPR_INFO, server, cq, tag);
Craig Tiller7156fca2015-07-15 13:54:20 -07001121
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001122 /* lock, and gather up some stuff to do */
Craig Tiller45724b32015-09-22 10:42:19 -07001123 gpr_mu_lock (&server->mu_global);
1124 grpc_cq_begin_op (cq);
1125 if (server->shutdown_published)
1126 {
1127 grpc_cq_end_op (cq, tag, 1, done_published_shutdown, NULL, gpr_malloc (sizeof (grpc_cq_completion)), &closure_list);
1128 gpr_mu_unlock (&server->mu_global);
1129 goto done;
1130 }
1131 server->shutdown_tags = gpr_realloc (server->shutdown_tags, sizeof (shutdown_tag) * (server->num_shutdown_tags + 1));
Craig Tillerbce999f2015-05-27 09:55:51 -07001132 sdt = &server->shutdown_tags[server->num_shutdown_tags++];
1133 sdt->tag = tag;
1134 sdt->cq = cq;
Craig Tiller45724b32015-09-22 10:42:19 -07001135 if (gpr_atm_acq_load (&server->shutdown_flag))
1136 {
1137 gpr_mu_unlock (&server->mu_global);
1138 goto done;
1139 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001140
Craig Tiller45724b32015-09-22 10:42:19 -07001141 server->last_shutdown_message_time = gpr_now (GPR_CLOCK_REALTIME);
Craig Tillerab54f792015-07-08 08:34:20 -07001142
Craig Tiller45724b32015-09-22 10:42:19 -07001143 channel_broadcaster_init (server, &broadcaster);
nnoble0c475f02014-12-05 15:37:39 -08001144
Craig Tillerbd217572015-02-11 18:10:56 -08001145 /* collect all unregistered then registered calls */
Craig Tiller45724b32015-09-22 10:42:19 -07001146 gpr_mu_lock (&server->mu_call);
1147 kill_pending_work_locked (server, &closure_list);
1148 gpr_mu_unlock (&server->mu_call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001149
Craig Tiller45724b32015-09-22 10:42:19 -07001150 gpr_atm_rel_store (&server->shutdown_flag, 1);
1151 maybe_finish_shutdown (server, &closure_list);
1152 gpr_mu_unlock (&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001153
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001154 /* Shutdown listeners */
Craig Tiller45724b32015-09-22 10:42:19 -07001155 for (l = server->listeners; l; l = l->next)
1156 {
1157 grpc_closure_init (&l->destroy_done, listener_destroy_done, server);
1158 l->destroy (server, l->arg, &l->destroy_done, &closure_list);
1159 }
Craig Tillerff3ae682015-06-29 17:44:04 -07001160
Craig Tiller45724b32015-09-22 10:42:19 -07001161 channel_broadcaster_shutdown (&broadcaster, 1, 0, &closure_list);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001162
Craig Tillerdfff1b82015-09-21 14:39:57 -07001163done:
Craig Tiller098047b2015-09-22 10:53:14 -07001164 grpc_exec_ctx_finish (&exec_ctx);
Craig Tilleraec96aa2015-04-07 14:32:15 -07001165}
1166
Craig Tiller45724b32015-09-22 10:42:19 -07001167void
1168grpc_server_cancel_all_calls (grpc_server * server)
1169{
Craig Tiller092d8d12015-07-04 22:35:00 -07001170 channel_broadcaster broadcaster;
Craig Tillerf5768a62015-09-22 10:54:34 -07001171 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tillerafa2d632015-05-26 16:39:13 -07001172
Craig Tiller45724b32015-09-22 10:42:19 -07001173 gpr_mu_lock (&server->mu_global);
1174 channel_broadcaster_init (server, &broadcaster);
1175 gpr_mu_unlock (&server->mu_global);
Craig Tillerafa2d632015-05-26 16:39:13 -07001176
Craig Tiller45724b32015-09-22 10:42:19 -07001177 channel_broadcaster_shutdown (&broadcaster, 0, 1, &closure_list);
Craig Tiller098047b2015-09-22 10:53:14 -07001178 grpc_exec_ctx_finish (&exec_ctx);
Craig Tillerafa2d632015-05-26 16:39:13 -07001179}
1180
Craig Tiller45724b32015-09-22 10:42:19 -07001181void
1182grpc_server_destroy (grpc_server * server)
1183{
Craig Tilleraec96aa2015-04-07 14:32:15 -07001184 listener *l;
Craig Tillerf5768a62015-09-22 10:54:34 -07001185 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller872af022015-04-24 15:57:52 -07001186
Craig Tiller45724b32015-09-22 10:42:19 -07001187 gpr_mu_lock (&server->mu_global);
1188 GPR_ASSERT (gpr_atm_acq_load (&server->shutdown_flag) || !server->listeners);
1189 GPR_ASSERT (server->listeners_destroyed == num_listeners (server));
Craig Tilleraec96aa2015-04-07 14:32:15 -07001190
Craig Tiller45724b32015-09-22 10:42:19 -07001191 while (server->listeners)
1192 {
1193 l = server->listeners;
1194 server->listeners = l->next;
1195 gpr_free (l);
1196 }
Craig Tilleraec96aa2015-04-07 14:32:15 -07001197
Craig Tiller45724b32015-09-22 10:42:19 -07001198 gpr_mu_unlock (&server->mu_global);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001199
Craig Tiller45724b32015-09-22 10:42:19 -07001200 server_unref (server, &closure_list);
Craig Tiller098047b2015-09-22 10:53:14 -07001201 grpc_exec_ctx_finish (&exec_ctx);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001202}
1203
Craig Tiller45724b32015-09-22 10:42:19 -07001204void
Craig Tiller1be70cc2015-09-22 10:45:28 -07001205grpc_server_add_listener (grpc_server * server, void *arg, void (*start) (grpc_exec_ctx * exec_ctx, grpc_server * server, void *arg, grpc_pollset ** pollsets, size_t pollset_count), void (*destroy) (grpc_exec_ctx * exec_ctx, grpc_server * server, void *arg, grpc_closure * on_done, grpc_closure_list * closure_list))
Craig Tiller45724b32015-09-22 10:42:19 -07001206{
1207 listener *l = gpr_malloc (sizeof (listener));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001208 l->arg = arg;
1209 l->start = start;
1210 l->destroy = destroy;
1211 l->next = server->listeners;
1212 server->listeners = l;
1213}
1214
Craig Tiller45724b32015-09-22 10:42:19 -07001215static grpc_call_error
Craig Tiller1be70cc2015-09-22 10:45:28 -07001216queue_call_request (grpc_exec_ctx * exec_ctx, grpc_server * server, requested_call * rc)
Craig Tiller45724b32015-09-22 10:42:19 -07001217{
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001218 call_data *calld = NULL;
Craig Tiller729b35a2015-07-13 12:36:47 -07001219 request_matcher *request_matcher = NULL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001220 int request_id;
Craig Tiller45724b32015-09-22 10:42:19 -07001221 if (gpr_atm_acq_load (&server->shutdown_flag))
1222 {
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001223 fail_call (exec_ctx, server, rc);
Craig Tiller45724b32015-09-22 10:42:19 -07001224 return GRPC_CALL_OK;
1225 }
1226 request_id = gpr_stack_lockfree_pop (server->request_freelist);
1227 if (request_id == -1)
1228 {
1229 /* out of request ids: just fail this one */
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001230 fail_call (exec_ctx, server, rc);
Craig Tiller45724b32015-09-22 10:42:19 -07001231 return GRPC_CALL_OK;
1232 }
1233 switch (rc->type)
1234 {
Craig Tiller04cc8be2015-02-10 16:11:22 -08001235 case BATCH_CALL:
Craig Tiller729b35a2015-07-13 12:36:47 -07001236 request_matcher = &server->unregistered_request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001237 break;
1238 case REGISTERED_CALL:
Craig Tiller729b35a2015-07-13 12:36:47 -07001239 request_matcher = &rc->data.registered.registered_method->request_matcher;
Craig Tiller04cc8be2015-02-10 16:11:22 -08001240 break;
Craig Tiller729b35a2015-07-13 12:36:47 -07001241 }
Craig Tiller45724b32015-09-22 10:42:19 -07001242 server->requested_calls[request_id] = *rc;
1243 gpr_free (rc);
1244 if (gpr_stack_lockfree_push (request_matcher->requests, request_id))
1245 {
1246 /* this was the first queued request: we need to lock and start
1247 matching calls */
1248 gpr_mu_lock (&server->mu_call);
1249 while ((calld = request_matcher->pending_head) != NULL)
1250 {
1251 request_id = gpr_stack_lockfree_pop (request_matcher->requests);
1252 if (request_id == -1)
1253 break;
1254 request_matcher->pending_head = calld->pending_next;
1255 gpr_mu_unlock (&server->mu_call);
1256 gpr_mu_lock (&calld->mu_state);
1257 if (calld->state == ZOMBIED)
1258 {
1259 gpr_mu_unlock (&calld->mu_state);
1260 grpc_closure_init (&calld->kill_zombie_closure, kill_zombie, grpc_call_stack_element (grpc_call_get_call_stack (calld->call), 0));
Craig Tiller8ad03752015-09-22 10:48:23 -07001261 grpc_exec_ctx_enqueue (exec_ctx, &calld->kill_zombie_closure, 1);
Craig Tiller45724b32015-09-22 10:42:19 -07001262 }
1263 else
1264 {
1265 GPR_ASSERT (calld->state == PENDING);
1266 calld->state = ACTIVATED;
1267 gpr_mu_unlock (&calld->mu_state);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001268 begin_call (exec_ctx, server, calld, &server->requested_calls[request_id]);
Craig Tiller45724b32015-09-22 10:42:19 -07001269 }
1270 gpr_mu_lock (&server->mu_call);
1271 }
1272 gpr_mu_unlock (&server->mu_call);
1273 }
Craig Tiller6a006ce2015-07-13 16:25:40 -07001274 return GRPC_CALL_OK;
Craig Tillercce17ac2015-01-20 09:29:28 -08001275}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001276
Craig Tiller45724b32015-09-22 10:42:19 -07001277grpc_call_error
1278grpc_server_request_call (grpc_server * server, grpc_call ** call, grpc_call_details * details, grpc_metadata_array * initial_metadata, grpc_completion_queue * cq_bound_to_call, grpc_completion_queue * cq_for_notification, void *tag)
1279{
Craig Tillerdfff1b82015-09-21 14:39:57 -07001280 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001281 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller45724b32015-09-22 10:42:19 -07001282 requested_call *rc = gpr_malloc (sizeof (*rc));
1283 GRPC_SERVER_LOG_REQUEST_CALL (GPR_INFO, server, call, details, initial_metadata, cq_bound_to_call, cq_for_notification, tag);
1284 if (!grpc_cq_is_server_cq (cq_for_notification))
1285 {
1286 gpr_free (rc);
1287 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1288 goto done;
1289 }
1290 grpc_cq_begin_op (cq_for_notification);
Craig Tiller9928d392015-08-18 09:40:24 -07001291 details->reserved = NULL;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001292 rc->type = BATCH_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001293 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001294 rc->tag = tag;
1295 rc->cq_bound_to_call = cq_bound_to_call;
1296 rc->cq_for_notification = cq_for_notification;
1297 rc->call = call;
1298 rc->data.batch.details = details;
1299 rc->data.batch.initial_metadata = initial_metadata;
Craig Tiller45724b32015-09-22 10:42:19 -07001300 error = queue_call_request (server, rc, &closure_list);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001301done:
Craig Tiller098047b2015-09-22 10:53:14 -07001302 grpc_exec_ctx_finish (&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001303 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001304}
1305
Craig Tiller45724b32015-09-22 10:42:19 -07001306grpc_call_error
1307grpc_server_request_registered_call (grpc_server * server, void *rm, grpc_call ** call, gpr_timespec * deadline, grpc_metadata_array * initial_metadata, grpc_byte_buffer ** optional_payload, grpc_completion_queue * cq_bound_to_call, grpc_completion_queue * cq_for_notification, void *tag)
1308{
Craig Tillerdfff1b82015-09-21 14:39:57 -07001309 grpc_call_error error;
Craig Tillerf5768a62015-09-22 10:54:34 -07001310 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
Craig Tiller45724b32015-09-22 10:42:19 -07001311 requested_call *rc = gpr_malloc (sizeof (*rc));
Craig Tiller20bc56d2015-02-12 09:02:56 -08001312 registered_method *registered_method = rm;
Craig Tiller45724b32015-09-22 10:42:19 -07001313 if (!grpc_cq_is_server_cq (cq_for_notification))
1314 {
1315 gpr_free (rc);
1316 error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
1317 goto done;
1318 }
1319 grpc_cq_begin_op (cq_for_notification);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001320 rc->type = REGISTERED_CALL;
Craig Tiller6a006ce2015-07-13 16:25:40 -07001321 rc->server = server;
Craig Tiller97fc6a32015-07-08 15:31:35 -07001322 rc->tag = tag;
1323 rc->cq_bound_to_call = cq_bound_to_call;
1324 rc->cq_for_notification = cq_for_notification;
1325 rc->call = call;
1326 rc->data.registered.registered_method = registered_method;
1327 rc->data.registered.deadline = deadline;
1328 rc->data.registered.initial_metadata = initial_metadata;
1329 rc->data.registered.optional_payload = optional_payload;
Craig Tiller45724b32015-09-22 10:42:19 -07001330 error = queue_call_request (server, rc, &closure_list);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001331done:
Craig Tiller098047b2015-09-22 10:53:14 -07001332 grpc_exec_ctx_finish (&exec_ctx);
Craig Tillerdfff1b82015-09-21 14:39:57 -07001333 return error;
Craig Tiller24be0f72015-02-10 14:04:22 -08001334}
1335
Craig Tiller1be70cc2015-09-22 10:45:28 -07001336static void publish_registered_or_batch (grpc_exec_ctx * exec_ctx, grpc_call * call, int success, void *tag);
Craig Tiller45724b32015-09-22 10:42:19 -07001337static void
Craig Tiller1be70cc2015-09-22 10:45:28 -07001338publish_was_not_set (grpc_exec_ctx * exec_ctx, grpc_call * call, int success, void *tag)
Craig Tiller45724b32015-09-22 10:42:19 -07001339{
1340 abort ();
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001341}
Craig Tiller24be0f72015-02-10 14:04:22 -08001342
Craig Tiller45724b32015-09-22 10:42:19 -07001343static void
1344cpstr (char **dest, size_t * capacity, grpc_mdstr * value)
1345{
Craig Tiller166e2502015-02-03 20:14:41 -08001346 gpr_slice slice = value->slice;
Craig Tiller45724b32015-09-22 10:42:19 -07001347 size_t len = GPR_SLICE_LENGTH (slice);
Craig Tiller166e2502015-02-03 20:14:41 -08001348
Craig Tiller45724b32015-09-22 10:42:19 -07001349 if (len + 1 > *capacity)
1350 {
1351 *capacity = GPR_MAX (len + 1, *capacity * 2);
1352 *dest = gpr_realloc (*dest, *capacity);
1353 }
1354 memcpy (*dest, grpc_mdstr_as_c_string (value), len + 1);
Craig Tiller166e2502015-02-03 20:14:41 -08001355}
1356
Craig Tiller45724b32015-09-22 10:42:19 -07001357static void
Craig Tiller1be70cc2015-09-22 10:45:28 -07001358begin_call (grpc_exec_ctx * exec_ctx, grpc_server * server, call_data * calld, requested_call * rc)
Craig Tiller45724b32015-09-22 10:42:19 -07001359{
Yang Gaoeb8e7cd2015-02-11 11:43:40 -08001360 grpc_ioreq_completion_func publish = publish_was_not_set;
Craig Tiller24be0f72015-02-10 14:04:22 -08001361 grpc_ioreq req[2];
1362 grpc_ioreq *r = req;
1363
1364 /* called once initial metadata has been read by the call, but BEFORE
1365 the ioreq to fetch it out of the call has been executed.
1366 This means metadata related fields can be relied on in calld, but to
1367 fill in the metadata array passed by the client, we need to perform
1368 an ioreq op, that should complete immediately. */
1369
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001370 grpc_call_set_completion_queue (exec_ctx, calld->call, rc->cq_bound_to_call);
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001371 *rc->call = calld->call;
1372 calld->cq_new = rc->cq_for_notification;
Craig Tiller45724b32015-09-22 10:42:19 -07001373 switch (rc->type)
1374 {
Craig Tiller24be0f72015-02-10 14:04:22 -08001375 case BATCH_CALL:
Craig Tiller45724b32015-09-22 10:42:19 -07001376 GPR_ASSERT (calld->host != NULL);
1377 GPR_ASSERT (calld->path != NULL);
1378 cpstr (&rc->data.batch.details->host, &rc->data.batch.details->host_capacity, calld->host);
1379 cpstr (&rc->data.batch.details->method, &rc->data.batch.details->method_capacity, calld->path);
Masood Malekghassemibf177c82015-04-27 12:14:38 -07001380 rc->data.batch.details->deadline = calld->deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -08001381 r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
1382 r->data.recv_metadata = rc->data.batch.initial_metadata;
David Garcia Quintasb8f54502015-06-15 16:19:10 -07001383 r->flags = 0;
Craig Tiller24be0f72015-02-10 14:04:22 -08001384 r++;
1385 publish = publish_registered_or_batch;
1386 break;
1387 case REGISTERED_CALL:
1388 *rc->data.registered.deadline = calld->deadline;
Craig Tiller24be0f72015-02-10 14:04:22 -08001389 r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
1390 r->data.recv_metadata = rc->data.registered.initial_metadata;
David Garcia Quintasb8f54502015-06-15 16:19:10 -07001391 r->flags = 0;
Craig Tiller24be0f72015-02-10 14:04:22 -08001392 r++;
Craig Tiller45724b32015-09-22 10:42:19 -07001393 if (rc->data.registered.optional_payload)
1394 {
1395 r->op = GRPC_IOREQ_RECV_MESSAGE;
1396 r->data.recv_message = rc->data.registered.optional_payload;
1397 r->flags = 0;
1398 r++;
1399 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001400 publish = publish_registered_or_batch;
1401 break;
Craig Tiller45724b32015-09-22 10:42:19 -07001402 }
Craig Tiller24be0f72015-02-10 14:04:22 -08001403
Craig Tiller45724b32015-09-22 10:42:19 -07001404 GRPC_CALL_INTERNAL_REF (calld->call, "server");
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001405 grpc_call_start_ioreq_and_call_back (calld->call, req, (size_t) (exec_ctx, r - req), publish, rc);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001406}
1407
Craig Tiller45724b32015-09-22 10:42:19 -07001408static void
Craig Tiller1be70cc2015-09-22 10:45:28 -07001409done_request_event (grpc_exec_ctx * exec_ctx, void *req, grpc_cq_completion * c)
Craig Tiller45724b32015-09-22 10:42:19 -07001410{
Craig Tiller6a006ce2015-07-13 16:25:40 -07001411 requested_call *rc = req;
1412 grpc_server *server = rc->server;
1413
Craig Tiller45724b32015-09-22 10:42:19 -07001414 if (rc >= server->requested_calls && rc < server->requested_calls + server->max_requested_calls)
1415 {
1416 GPR_ASSERT (rc - server->requested_calls <= INT_MAX);
1417 gpr_stack_lockfree_push (server->request_freelist, (int) (rc - server->requested_calls));
1418 }
1419 else
1420 {
1421 gpr_free (req);
1422 }
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001423
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001424 server_unref (exec_ctx, server);
Craig Tiller24be0f72015-02-10 14:04:22 -08001425}
1426
Craig Tiller45724b32015-09-22 10:42:19 -07001427static void
Craig Tiller1be70cc2015-09-22 10:45:28 -07001428fail_call (grpc_exec_ctx * exec_ctx, grpc_server * server, requested_call * rc)
Craig Tiller45724b32015-09-22 10:42:19 -07001429{
Craig Tillerf9e6adf2015-05-06 11:45:59 -07001430 *rc->call = NULL;
Craig Tiller45724b32015-09-22 10:42:19 -07001431 switch (rc->type)
1432 {
Craig Tiller24be0f72015-02-10 14:04:22 -08001433 case BATCH_CALL:
Craig Tiller24be0f72015-02-10 14:04:22 -08001434 rc->data.batch.initial_metadata->count = 0;
Craig Tiller24be0f72015-02-10 14:04:22 -08001435 break;
1436 case REGISTERED_CALL:
Craig Tiller24be0f72015-02-10 14:04:22 -08001437 rc->data.registered.initial_metadata->count = 0;
Craig Tiller24be0f72015-02-10 14:04:22 -08001438 break;
Craig Tiller45724b32015-09-22 10:42:19 -07001439 }
1440 server_ref (server);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001441 grpc_cq_end_op (exec_ctx, rc->cq_for_notification, rc->tag, 0, done_request_event, rc, &rc->completion);
Craig Tiller24be0f72015-02-10 14:04:22 -08001442}
1443
Craig Tiller45724b32015-09-22 10:42:19 -07001444static void
Craig Tiller1be70cc2015-09-22 10:45:28 -07001445publish_registered_or_batch (grpc_exec_ctx * exec_ctx, grpc_call * call, int success, void *prc)
Craig Tiller45724b32015-09-22 10:42:19 -07001446{
1447 grpc_call_element *elem = grpc_call_stack_element (grpc_call_get_call_stack (call), 0);
Craig Tiller97fc6a32015-07-08 15:31:35 -07001448 requested_call *rc = prc;
Craig Tiller20bc56d2015-02-12 09:02:56 -08001449 call_data *calld = elem->call_data;
Craig Tillere2b3bfa2015-07-30 10:40:22 -07001450 channel_data *chand = elem->channel_data;
Craig Tiller45724b32015-09-22 10:42:19 -07001451 server_ref (chand->server);
Craig Tiller9f7dc3a2015-09-22 10:47:08 -07001452 grpc_cq_end_op (exec_ctx, calld->cq_new, rc->tag, success, done_request_event, rc, &rc->completion);
1453 GRPC_CALL_INTERNAL_UNREF (exec_ctx, call, "server");
Craig Tiller24be0f72015-02-10 14:04:22 -08001454}
1455
Craig Tiller45724b32015-09-22 10:42:19 -07001456const grpc_channel_args *
1457grpc_server_get_channel_args (grpc_server * server)
1458{
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001459 return server->channel_args;
Craig Tiller190d3602015-02-18 09:23:38 -08001460}
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001461
Craig Tiller45724b32015-09-22 10:42:19 -07001462int
1463grpc_server_has_open_connections (grpc_server * server)
1464{
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001465 int r;
Craig Tiller45724b32015-09-22 10:42:19 -07001466 gpr_mu_lock (&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001467 r = server->root_channel_data.next != &server->root_channel_data;
Craig Tiller45724b32015-09-22 10:42:19 -07001468 gpr_mu_unlock (&server->mu_global);
Craig Tillerba3c3cd2015-05-26 06:28:10 -07001469 return r;
1470}