blob: 81eaf4fc940e08b1be043f3d1dccc13b418f230c [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
3 * Copyright 2014, Google Inc.
4 * 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
36#include <stdlib.h>
37#include <string.h>
38
39#include "src/core/channel/census_filter.h"
40#include "src/core/channel/channel_args.h"
41#include "src/core/channel/connected_channel.h"
ctiller18b49ab2014-12-09 14:39:16 -080042#include "src/core/iomgr/iomgr.h"
Craig Tiller485d7762015-01-23 12:54:05 -080043#include "src/core/support/string.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080044#include "src/core/surface/call.h"
45#include "src/core/surface/channel.h"
46#include "src/core/surface/completion_queue.h"
Craig Tillercce17ac2015-01-20 09:29:28 -080047#include "src/core/transport/metadata.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080048#include <grpc/support/alloc.h>
49#include <grpc/support/log.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080050#include <grpc/support/useful.h>
51
52typedef enum { PENDING_START, ALL_CALLS, CALL_LIST_COUNT } call_list;
53
54typedef struct listener {
55 void *arg;
ctiller58393c22015-01-07 14:03:30 -080056 void (*start)(grpc_server *server, void *arg, grpc_pollset *pollset);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080057 void (*destroy)(grpc_server *server, void *arg);
58 struct listener *next;
59} listener;
60
61typedef struct call_data call_data;
62typedef struct channel_data channel_data;
Craig Tiller24be0f72015-02-10 14:04:22 -080063typedef struct registered_method registered_method;
64
65typedef struct {
66 call_data *next;
67 call_data *prev;
68} call_link;
69
70typedef enum { LEGACY_CALL, BATCH_CALL, REGISTERED_CALL } requested_call_type;
71
72typedef struct {
73 requested_call_type type;
74 void *tag;
75 union {
76 struct {
77 grpc_completion_queue *cq;
78 grpc_call **call;
79 grpc_call_details *details;
80 grpc_metadata_array *initial_metadata;
81 } batch;
82 struct {
83 grpc_completion_queue *cq;
84 grpc_call **call;
85 registered_method *registered_method;
86 gpr_timespec *deadline;
87 grpc_metadata_array *initial_metadata;
88 grpc_byte_buffer **optional_payload;
89 } registered;
90 } data;
91} requested_call;
92
93typedef struct {
94 requested_call *calls;
95 size_t count;
96 size_t capacity;
97} requested_call_array;
98
99struct registered_method {
100 char *method;
101 char *host;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800102 call_data *pending;
Craig Tiller24be0f72015-02-10 14:04:22 -0800103 requested_call_array requested;
104 registered_method *next;
105};
106
107typedef struct channel_registered_method {
108 registered_method *server_registered_method;
109 grpc_mdstr *method;
110 grpc_mdstr *host;
111} channel_registered_method;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800112
113struct channel_data {
114 grpc_server *server;
115 grpc_channel *channel;
Craig Tillercce17ac2015-01-20 09:29:28 -0800116 grpc_mdstr *path_key;
117 grpc_mdstr *authority_key;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800118 /* linked list of all channels on a server */
119 channel_data *next;
120 channel_data *prev;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800121 channel_registered_method *registered_methods;
122 gpr_uint32 registered_method_slots;
123 gpr_uint32 registered_method_max_probes;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800124};
125
126struct grpc_server {
127 size_t channel_filter_count;
128 const grpc_channel_filter **channel_filters;
129 grpc_channel_args *channel_args;
130 grpc_completion_queue *cq;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800131
132 gpr_mu mu;
133
Craig Tiller24be0f72015-02-10 14:04:22 -0800134 registered_method *registered_methods;
135 requested_call_array requested_calls;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800136
137 gpr_uint8 shutdown;
Craig Tiller4ffdcd52015-01-16 11:34:55 -0800138 gpr_uint8 have_shutdown_tag;
139 void *shutdown_tag;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800140
141 call_data *lists[CALL_LIST_COUNT];
142 channel_data root_channel_data;
143
144 listener *listeners;
145 gpr_refcount internal_refcount;
146};
147
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800148typedef enum {
149 /* waiting for metadata */
150 NOT_STARTED,
151 /* inital metadata read, not flow controlled in yet */
152 PENDING,
153 /* flow controlled in, on completion queue */
154 ACTIVATED,
155 /* cancelled before being queued */
156 ZOMBIED
157} call_state;
158
Craig Tillerfb189f82015-02-03 12:07:07 -0800159typedef struct legacy_data {
Craig Tiller24be0f72015-02-10 14:04:22 -0800160 grpc_metadata_array initial_metadata;
Craig Tillerfb189f82015-02-03 12:07:07 -0800161} legacy_data;
Craig Tillercce17ac2015-01-20 09:29:28 -0800162
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800163struct call_data {
164 grpc_call *call;
165
166 call_state state;
167 gpr_timespec deadline;
Craig Tillercce17ac2015-01-20 09:29:28 -0800168 grpc_mdstr *path;
169 grpc_mdstr *host;
170
171 legacy_data *legacy;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800172
Craig Tiller04cc8be2015-02-10 16:11:22 -0800173 call_data **root[CALL_LIST_COUNT];
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800174 call_link links[CALL_LIST_COUNT];
175};
176
177#define SERVER_FROM_CALL_ELEM(elem) \
178 (((channel_data *)(elem)->channel_data)->server)
179
180static void do_nothing(void *unused, grpc_op_error ignored) {}
181
Craig Tiller24be0f72015-02-10 14:04:22 -0800182static void begin_call(grpc_server *server, call_data *calld,
183 requested_call *rc);
184static void fail_call(grpc_server *server, requested_call *rc);
185
Craig Tiller04cc8be2015-02-10 16:11:22 -0800186static int call_list_join(call_data **root, call_data *call,
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800187 call_list list) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800188 GPR_ASSERT(!call->root[list]);
189 call->root[list] = root;
190 if (!*root) {
191 *root = call;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800192 call->links[list].next = call->links[list].prev = call;
193 } else {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800194 call->links[list].next = *root;
195 call->links[list].prev = (*root)->links[list].prev;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800196 call->links[list].next->links[list].prev =
197 call->links[list].prev->links[list].next = call;
198 }
199 return 1;
200}
201
Craig Tiller04cc8be2015-02-10 16:11:22 -0800202static call_data *call_list_remove_head(call_data **root, call_list list) {
203 call_data *out = *root;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800204 if (out) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800205 out->root[list] = NULL;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800206 if (out->links[list].next == out) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800207 *root = NULL;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800208 } else {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800209 *root = out->links[list].next;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800210 out->links[list].next->links[list].prev = out->links[list].prev;
211 out->links[list].prev->links[list].next = out->links[list].next;
212 }
213 }
214 return out;
215}
216
Craig Tiller04cc8be2015-02-10 16:11:22 -0800217static int call_list_remove(call_data *call, call_list list) {
218 call_data **root = call->root[list];
219 if (root == NULL) return 0;
220 call->root[list] = NULL;
221 if (*root == call) {
222 *root = call->links[list].next;
223 if (*root == call) {
224 *root = NULL;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800225 return 1;
226 }
227 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800228 GPR_ASSERT(*root != call);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800229 call->links[list].next->links[list].prev = call->links[list].prev;
230 call->links[list].prev->links[list].next = call->links[list].next;
231 return 1;
232}
233
Craig Tiller24be0f72015-02-10 14:04:22 -0800234static void requested_call_array_destroy(requested_call_array *array) {
235 gpr_free(array->calls);
236}
237
238static requested_call *requested_call_array_add(requested_call_array *array) {
239 requested_call *rc;
240 if (array->count == array->capacity) {
241 array->capacity = GPR_MAX(array->capacity + 8, array->capacity * 2);
242 array->calls =
243 gpr_realloc(array->calls, sizeof(requested_call) * array->capacity);
244 }
245 rc = &array->calls[array->count++];
246 memset(rc, 0, sizeof(*rc));
247 return rc;
248}
249
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800250static void server_ref(grpc_server *server) {
251 gpr_ref(&server->internal_refcount);
252}
253
254static void server_unref(grpc_server *server) {
255 if (gpr_unref(&server->internal_refcount)) {
256 grpc_channel_args_destroy(server->channel_args);
257 gpr_mu_destroy(&server->mu);
258 gpr_free(server->channel_filters);
Craig Tiller24be0f72015-02-10 14:04:22 -0800259 requested_call_array_destroy(&server->requested_calls);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800260 gpr_free(server);
261 }
262}
263
264static int is_channel_orphaned(channel_data *chand) {
265 return chand->next == chand;
266}
267
268static void orphan_channel(channel_data *chand) {
269 chand->next->prev = chand->prev;
270 chand->prev->next = chand->next;
271 chand->next = chand->prev = chand;
272}
273
ctiller58393c22015-01-07 14:03:30 -0800274static void finish_destroy_channel(void *cd, int success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800275 channel_data *chand = cd;
276 grpc_server *server = chand->server;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800277 grpc_channel_destroy(chand->channel);
278 server_unref(server);
279}
280
281static void destroy_channel(channel_data *chand) {
282 if (is_channel_orphaned(chand)) return;
283 GPR_ASSERT(chand->server != NULL);
284 orphan_channel(chand);
285 server_ref(chand->server);
ctiller18b49ab2014-12-09 14:39:16 -0800286 grpc_iomgr_add_callback(finish_destroy_channel, chand);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800287}
288
Craig Tiller04cc8be2015-02-10 16:11:22 -0800289static void finish_start_new_rpc_and_unlock(grpc_server *server, grpc_call_element *elem, call_data **pending_root, requested_call_array *array) {
290 requested_call rc;
291 call_data *calld = elem->call_data;
292 if (array->count == 0) {
293 calld->state = PENDING;
294 call_list_join(pending_root, calld, PENDING_START);
295 gpr_mu_unlock(&server->mu);
296 } else {
297 rc = server->requested_calls.calls[--server->requested_calls.count];
298 calld->state = ACTIVATED;
299 gpr_mu_unlock(&server->mu);
300 begin_call(server, calld, &rc);
301 }
302}
303
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800304static void start_new_rpc(grpc_call_element *elem) {
305 channel_data *chand = elem->channel_data;
306 call_data *calld = elem->call_data;
307 grpc_server *server = chand->server;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800308 gpr_uint32 i;
309 gpr_uint32 hash;
310 channel_registered_method *rm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800311
312 gpr_mu_lock(&server->mu);
Craig Tiller04cc8be2015-02-10 16:11:22 -0800313 if (chand->registered_methods && calld->path && calld->host) {
314 /* check for an exact match with host */
315 hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash);
316 for (i = 0; i < chand->registered_method_max_probes; i++) {
317 rm = &chand->registered_methods[(hash + i) % chand->registered_method_slots];
318 if (!rm) break;
319 if (rm->host != calld->host) continue;
320 if (rm->method != calld->path) continue;
321 finish_start_new_rpc_and_unlock(server, elem, &rm->server_registered_method->pending, &rm->server_registered_method->requested);
322 return;
323 }
324 /* check for a wildcard method definition (no host set) */
325 hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash);
326 for (i = 0; i < chand->registered_method_max_probes; i++) {
327 rm = &chand->registered_methods[(hash + i) % chand->registered_method_slots];
328 if (!rm) break;
329 if (rm->host != NULL) continue;
330 if (rm->method != calld->path) continue;
331 finish_start_new_rpc_and_unlock(server, elem, &rm->server_registered_method->pending, &rm->server_registered_method->requested);
332 return;
333 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800334 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800335 finish_start_new_rpc_and_unlock(server, elem, &server->lists[PENDING_START], &server->requested_calls);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800336}
337
ctiller58393c22015-01-07 14:03:30 -0800338static void kill_zombie(void *elem, int success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800339 grpc_call_destroy(grpc_call_from_top_element(elem));
340}
341
Craig Tillercce17ac2015-01-20 09:29:28 -0800342static void stream_closed(grpc_call_element *elem) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800343 call_data *calld = elem->call_data;
344 channel_data *chand = elem->channel_data;
345 gpr_mu_lock(&chand->server->mu);
346 switch (calld->state) {
347 case ACTIVATED:
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800348 break;
349 case PENDING:
Craig Tiller04cc8be2015-02-10 16:11:22 -0800350 call_list_remove(calld, PENDING_START);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800351 /* fallthrough intended */
352 case NOT_STARTED:
353 calld->state = ZOMBIED;
ctiller18b49ab2014-12-09 14:39:16 -0800354 grpc_iomgr_add_callback(kill_zombie, elem);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800355 break;
356 case ZOMBIED:
357 break;
358 }
359 gpr_mu_unlock(&chand->server->mu);
Craig Tiller0a927bf2015-02-05 10:52:53 -0800360 grpc_call_stream_closed(elem);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800361}
362
Craig Tillercce17ac2015-01-20 09:29:28 -0800363static void read_closed(grpc_call_element *elem) {
364 call_data *calld = elem->call_data;
365 channel_data *chand = elem->channel_data;
366 gpr_mu_lock(&chand->server->mu);
367 switch (calld->state) {
368 case ACTIVATED:
369 case PENDING:
370 grpc_call_read_closed(elem);
371 break;
372 case NOT_STARTED:
373 calld->state = ZOMBIED;
374 grpc_iomgr_add_callback(kill_zombie, elem);
375 break;
376 case ZOMBIED:
377 break;
378 }
379 gpr_mu_unlock(&chand->server->mu);
380}
381
ctillerf962f522014-12-10 15:28:27 -0800382static void call_op(grpc_call_element *elem, grpc_call_element *from_elemn,
383 grpc_call_op *op) {
Craig Tillercce17ac2015-01-20 09:29:28 -0800384 channel_data *chand = elem->channel_data;
385 call_data *calld = elem->call_data;
386 grpc_mdelem *md;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800387 GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
388 switch (op->type) {
389 case GRPC_RECV_METADATA:
Craig Tillercce17ac2015-01-20 09:29:28 -0800390 md = op->data.metadata;
391 if (md->key == chand->path_key) {
392 calld->path = grpc_mdstr_ref(md->value);
393 grpc_mdelem_unref(md);
394 } else if (md->key == chand->authority_key) {
395 calld->host = grpc_mdstr_ref(md->value);
396 grpc_mdelem_unref(md);
397 } else {
398 grpc_call_recv_metadata(elem, md);
399 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800400 break;
401 case GRPC_RECV_END_OF_INITIAL_METADATA:
402 start_new_rpc(elem);
Craig Tiller4069b682015-01-29 14:01:19 -0800403 grpc_call_initial_metadata_complete(elem);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800404 break;
405 case GRPC_RECV_MESSAGE:
Craig Tillercce17ac2015-01-20 09:29:28 -0800406 grpc_call_recv_message(elem, op->data.message);
407 op->done_cb(op->user_data, GRPC_OP_OK);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800408 break;
409 case GRPC_RECV_HALF_CLOSE:
Craig Tillercce17ac2015-01-20 09:29:28 -0800410 read_closed(elem);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800411 break;
412 case GRPC_RECV_FINISH:
Craig Tillercce17ac2015-01-20 09:29:28 -0800413 stream_closed(elem);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800414 break;
415 case GRPC_RECV_DEADLINE:
416 grpc_call_set_deadline(elem, op->data.deadline);
417 ((call_data *)elem->call_data)->deadline = op->data.deadline;
418 break;
419 default:
420 GPR_ASSERT(op->dir == GRPC_CALL_DOWN);
421 grpc_call_next_op(elem, op);
422 break;
423 }
424}
425
ctillerf962f522014-12-10 15:28:27 -0800426static void channel_op(grpc_channel_element *elem,
427 grpc_channel_element *from_elem, grpc_channel_op *op) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800428 channel_data *chand = elem->channel_data;
Craig Tiller8b976d02015-02-05 21:41:23 -0800429 grpc_server *server = chand->server;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800430
431 switch (op->type) {
432 case GRPC_ACCEPT_CALL:
433 /* create a call */
Craig Tillerfb189f82015-02-03 12:07:07 -0800434 grpc_call_create(chand->channel, NULL,
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800435 op->data.accept_call.transport_server_data);
436 break;
437 case GRPC_TRANSPORT_CLOSED:
438 /* if the transport is closed for a server channel, we destroy the
439 channel */
Craig Tiller8b976d02015-02-05 21:41:23 -0800440 gpr_mu_lock(&server->mu);
441 server_ref(server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800442 destroy_channel(chand);
Craig Tiller8b976d02015-02-05 21:41:23 -0800443 gpr_mu_unlock(&server->mu);
444 server_unref(server);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800445 break;
nnoble0c475f02014-12-05 15:37:39 -0800446 case GRPC_TRANSPORT_GOAWAY:
447 gpr_slice_unref(op->data.goaway.message);
448 break;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800449 default:
450 GPR_ASSERT(op->dir == GRPC_CALL_DOWN);
451 grpc_channel_next_op(elem, op);
452 break;
453 }
454}
455
ctiller58393c22015-01-07 14:03:30 -0800456static void finish_shutdown_channel(void *cd, int success) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800457 channel_data *chand = cd;
458 grpc_channel_op op;
nnoble0c475f02014-12-05 15:37:39 -0800459 op.type = GRPC_CHANNEL_DISCONNECT;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800460 op.dir = GRPC_CALL_DOWN;
461 channel_op(grpc_channel_stack_element(
462 grpc_channel_get_channel_stack(chand->channel), 0),
ctillerf962f522014-12-10 15:28:27 -0800463 NULL, &op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800464 grpc_channel_internal_unref(chand->channel);
465}
466
467static void shutdown_channel(channel_data *chand) {
468 grpc_channel_internal_ref(chand->channel);
ctiller18b49ab2014-12-09 14:39:16 -0800469 grpc_iomgr_add_callback(finish_shutdown_channel, chand);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800470}
471
472static void init_call_elem(grpc_call_element *elem,
473 const void *server_transport_data) {
474 call_data *calld = elem->call_data;
475 channel_data *chand = elem->channel_data;
476 memset(calld, 0, sizeof(call_data));
477 calld->deadline = gpr_inf_future;
478 calld->call = grpc_call_from_top_element(elem);
479
480 gpr_mu_lock(&chand->server->mu);
Craig Tiller04cc8be2015-02-10 16:11:22 -0800481 call_list_join(&chand->server->lists[ALL_CALLS], calld, ALL_CALLS);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800482 gpr_mu_unlock(&chand->server->mu);
483
484 server_ref(chand->server);
485}
486
487static void destroy_call_elem(grpc_call_element *elem) {
488 channel_data *chand = elem->channel_data;
Craig Tillerdb7db992015-01-29 11:19:01 -0800489 call_data *calld = elem->call_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800490 int i;
491
492 gpr_mu_lock(&chand->server->mu);
493 for (i = 0; i < CALL_LIST_COUNT; i++) {
Craig Tiller04cc8be2015-02-10 16:11:22 -0800494 call_list_remove(elem->call_data, i);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800495 }
Craig Tiller4ffdcd52015-01-16 11:34:55 -0800496 if (chand->server->shutdown && chand->server->have_shutdown_tag &&
497 chand->server->lists[ALL_CALLS] == NULL) {
498 grpc_cq_end_server_shutdown(chand->server->cq, chand->server->shutdown_tag);
499 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800500 gpr_mu_unlock(&chand->server->mu);
501
Craig Tiller4df31a62015-01-30 09:44:31 -0800502 if (calld->host) {
503 grpc_mdstr_unref(calld->host);
504 }
505 if (calld->path) {
506 grpc_mdstr_unref(calld->path);
507 }
508
Craig Tillerdb7db992015-01-29 11:19:01 -0800509 if (calld->legacy) {
Craig Tiller24be0f72015-02-10 14:04:22 -0800510 gpr_free(calld->legacy->initial_metadata.metadata);
Craig Tillerdb7db992015-01-29 11:19:01 -0800511 gpr_free(calld->legacy);
512 }
513
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800514 server_unref(chand->server);
515}
516
517static void init_channel_elem(grpc_channel_element *elem,
518 const grpc_channel_args *args,
519 grpc_mdctx *metadata_context, int is_first,
520 int is_last) {
521 channel_data *chand = elem->channel_data;
522 GPR_ASSERT(is_first);
523 GPR_ASSERT(!is_last);
524 chand->server = NULL;
525 chand->channel = NULL;
Craig Tillercce17ac2015-01-20 09:29:28 -0800526 chand->path_key = grpc_mdstr_from_string(metadata_context, ":path");
527 chand->authority_key = grpc_mdstr_from_string(metadata_context, ":authority");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800528 chand->next = chand->prev = chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800529 chand->registered_methods = NULL;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800530}
531
532static void destroy_channel_elem(grpc_channel_element *elem) {
533 channel_data *chand = elem->channel_data;
534 if (chand->server) {
535 gpr_mu_lock(&chand->server->mu);
536 chand->next->prev = chand->prev;
537 chand->prev->next = chand->next;
538 chand->next = chand->prev = chand;
539 gpr_mu_unlock(&chand->server->mu);
Craig Tillercce17ac2015-01-20 09:29:28 -0800540 grpc_mdstr_unref(chand->path_key);
541 grpc_mdstr_unref(chand->authority_key);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800542 server_unref(chand->server);
543 }
544}
545
546static const grpc_channel_filter server_surface_filter = {
Craig Tiller24be0f72015-02-10 14:04:22 -0800547 call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
548 sizeof(channel_data), init_channel_elem, destroy_channel_elem, "server",
Craig Tiller9f28ac22015-01-27 17:01:29 -0800549};
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800550
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800551grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
552 grpc_channel_filter **filters,
553 size_t filter_count,
554 const grpc_channel_args *args) {
555 size_t i;
556 int census_enabled = grpc_channel_args_is_census_enabled(args);
557
558 grpc_server *server = gpr_malloc(sizeof(grpc_server));
559 memset(server, 0, sizeof(grpc_server));
560
561 gpr_mu_init(&server->mu);
562
563 server->cq = cq;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800564 /* decremented by grpc_server_destroy */
565 gpr_ref_init(&server->internal_refcount, 1);
566 server->root_channel_data.next = server->root_channel_data.prev =
567 &server->root_channel_data;
568
569 /* Server filter stack is:
570
571 server_surface_filter - for making surface API calls
572 grpc_server_census_filter (optional) - for stats collection and tracing
573 {passed in filter stack}
574 grpc_connected_channel_filter - for interfacing with transports */
575 server->channel_filter_count = filter_count + 1 + census_enabled;
576 server->channel_filters =
577 gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *));
578 server->channel_filters[0] = &server_surface_filter;
579 if (census_enabled) {
580 server->channel_filters[1] = &grpc_server_census_filter;
581 }
582 for (i = 0; i < filter_count; i++) {
583 server->channel_filters[i + 1 + census_enabled] = filters[i];
584 }
585
586 server->channel_args = grpc_channel_args_copy(args);
587
588 return server;
589}
590
Craig Tiller24be0f72015-02-10 14:04:22 -0800591static int streq(const char *a, const char *b) {
592 if (a == NULL && b == NULL) return 1;
593 if (a == NULL) return 0;
594 if (b == NULL) return 0;
595 return 0 == strcmp(a, b);
596}
597
598void *grpc_server_register_method(grpc_server *server, const char *method,
599 const char *host) {
600 registered_method *m;
601 if (!method) {
602 gpr_log(GPR_ERROR, "%s method string cannot be NULL", __FUNCTION__);
603 return NULL;
604 }
605 for (m = server->registered_methods; m; m = m->next) {
606 if (streq(m->method, method) && streq(m->host, host)) {
607 gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
608 host ? host : "*");
609 return NULL;
610 }
611 }
612 m = gpr_malloc(sizeof(registered_method));
613 memset(m, 0, sizeof(*m));
614 m->method = gpr_strdup(method);
615 m->host = gpr_strdup(host);
616 m->next = server->registered_methods;
617 server->registered_methods = m;
618 return m;
619}
620
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800621void grpc_server_start(grpc_server *server) {
622 listener *l;
623
624 for (l = server->listeners; l; l = l->next) {
ctiller58393c22015-01-07 14:03:30 -0800625 l->start(server, l->arg, grpc_cq_pollset(server->cq));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800626 }
627}
628
629grpc_transport_setup_result grpc_server_setup_transport(
630 grpc_server *s, grpc_transport *transport,
631 grpc_channel_filter const **extra_filters, size_t num_extra_filters,
632 grpc_mdctx *mdctx) {
633 size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
634 grpc_channel_filter const **filters =
635 gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
636 size_t i;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800637 size_t num_registered_methods;
638 size_t alloc;
639 registered_method *rm;
640 channel_registered_method *crm;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800641 grpc_channel *channel;
642 channel_data *chand;
Craig Tiller04cc8be2015-02-10 16:11:22 -0800643 grpc_mdstr *host;
644 grpc_mdstr *method;
645 gpr_uint32 hash;
646 gpr_uint32 slots;
647 gpr_uint32 probes;
648 gpr_uint32 max_probes = 0;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800649
650 for (i = 0; i < s->channel_filter_count; i++) {
651 filters[i] = s->channel_filters[i];
652 }
653 for (; i < s->channel_filter_count + num_extra_filters; i++) {
654 filters[i] = extra_filters[i - s->channel_filter_count];
655 }
656 filters[i] = &grpc_connected_channel_filter;
657
ctillerd79b4862014-12-17 16:36:59 -0800658 grpc_transport_add_to_pollset(transport, grpc_cq_pollset(s->cq));
659
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800660 channel = grpc_channel_create_from_filters(filters, num_filters,
661 s->channel_args, mdctx, 0);
662 chand = (channel_data *)grpc_channel_stack_element(
663 grpc_channel_get_channel_stack(channel), 0)->channel_data;
664 chand->server = s;
665 server_ref(s);
666 chand->channel = channel;
667
Craig Tiller04cc8be2015-02-10 16:11:22 -0800668 num_registered_methods = 0;
669 for (rm = s->registered_methods; rm; rm = rm->next) {
670 num_registered_methods++;
671 }
672 /* build a lookup table phrased in terms of mdstr's in this channels context
673 to quickly find registered methods */
674 if (num_registered_methods > 0) {
675 slots = 2 * num_registered_methods;
676 alloc = sizeof(channel_registered_method) * slots;
677 chand->registered_methods = gpr_malloc(alloc);
678 memset(chand->registered_methods, 0, alloc);
679 for (rm = s->registered_methods; rm; rm = rm->next) {
680 host = rm->host ? grpc_mdstr_from_string(mdctx, rm->host) : NULL;
681 method = grpc_mdstr_from_string(mdctx, rm->host);
682 hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
683 for (probes = 0; chand->registered_methods[(hash + probes) % slots].server_registered_method != NULL; probes++);
684 if (probes > max_probes) max_probes = probes;
685 crm = &chand->registered_methods[(hash + probes) % slots];
686 crm->server_registered_method = rm;
687 crm->host = host;
688 crm->method = method;
689 }
690 chand->registered_method_slots = slots;
691 chand->registered_method_max_probes = max_probes;
692 }
693
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800694 gpr_mu_lock(&s->mu);
695 chand->next = &s->root_channel_data;
696 chand->prev = chand->next->prev;
697 chand->next->prev = chand->prev->next = chand;
698 gpr_mu_unlock(&s->mu);
699
700 gpr_free(filters);
701
702 return grpc_connected_channel_bind_transport(
703 grpc_channel_get_channel_stack(channel), transport);
704}
705
Craig Tiller4ffdcd52015-01-16 11:34:55 -0800706void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
707 void *shutdown_tag) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800708 listener *l;
Craig Tiller24be0f72015-02-10 14:04:22 -0800709 requested_call_array requested_calls;
nnoble0c475f02014-12-05 15:37:39 -0800710 channel_data **channels;
711 channel_data *c;
712 size_t nchannels;
713 size_t i;
714 grpc_channel_op op;
715 grpc_channel_element *elem;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800716
717 /* lock, and gather up some stuff to do */
718 gpr_mu_lock(&server->mu);
719 if (server->shutdown) {
720 gpr_mu_unlock(&server->mu);
721 return;
722 }
723
nnoble0c475f02014-12-05 15:37:39 -0800724 nchannels = 0;
725 for (c = server->root_channel_data.next; c != &server->root_channel_data;
726 c = c->next) {
727 nchannels++;
728 }
729 channels = gpr_malloc(sizeof(channel_data *) * nchannels);
730 i = 0;
731 for (c = server->root_channel_data.next; c != &server->root_channel_data;
732 c = c->next) {
733 grpc_channel_internal_ref(c->channel);
734 channels[i] = c;
735 i++;
736 }
737
Craig Tillercce17ac2015-01-20 09:29:28 -0800738 requested_calls = server->requested_calls;
Craig Tiller24be0f72015-02-10 14:04:22 -0800739 memset(&server->requested_calls, 0, sizeof(server->requested_calls));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800740
741 server->shutdown = 1;
Craig Tiller4ffdcd52015-01-16 11:34:55 -0800742 server->have_shutdown_tag = have_shutdown_tag;
743 server->shutdown_tag = shutdown_tag;
744 if (have_shutdown_tag) {
745 grpc_cq_begin_op(server->cq, NULL, GRPC_SERVER_SHUTDOWN);
746 if (server->lists[ALL_CALLS] == NULL) {
747 grpc_cq_end_server_shutdown(server->cq, shutdown_tag);
748 }
749 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800750 gpr_mu_unlock(&server->mu);
751
nnoble0c475f02014-12-05 15:37:39 -0800752 for (i = 0; i < nchannels; i++) {
753 c = channels[i];
754 elem = grpc_channel_stack_element(
755 grpc_channel_get_channel_stack(c->channel), 0);
756
757 op.type = GRPC_CHANNEL_GOAWAY;
758 op.dir = GRPC_CALL_DOWN;
759 op.data.goaway.status = GRPC_STATUS_OK;
760 op.data.goaway.message = gpr_slice_from_copied_string("Server shutdown");
ctillerf962f522014-12-10 15:28:27 -0800761 elem->filter->channel_op(elem, NULL, &op);
nnoble0c475f02014-12-05 15:37:39 -0800762
763 grpc_channel_internal_unref(c->channel);
764 }
765 gpr_free(channels);
766
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800767 /* terminate all the requested calls */
Craig Tiller24be0f72015-02-10 14:04:22 -0800768 for (i = 0; i < requested_calls.count; i++) {
769 fail_call(server, &requested_calls.calls[i]);
Craig Tillercce17ac2015-01-20 09:29:28 -0800770 }
Craig Tiller24be0f72015-02-10 14:04:22 -0800771 gpr_free(requested_calls.calls);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800772
773 /* Shutdown listeners */
774 for (l = server->listeners; l; l = l->next) {
775 l->destroy(server, l->arg);
776 }
777 while (server->listeners) {
778 l = server->listeners;
779 server->listeners = l->next;
780 gpr_free(l);
781 }
782}
783
Craig Tiller4ffdcd52015-01-16 11:34:55 -0800784void grpc_server_shutdown(grpc_server *server) {
785 shutdown_internal(server, 0, NULL);
786}
787
788void grpc_server_shutdown_and_notify(grpc_server *server, void *tag) {
789 shutdown_internal(server, 1, tag);
790}
791
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800792void grpc_server_destroy(grpc_server *server) {
793 channel_data *c;
794 gpr_mu_lock(&server->mu);
795 for (c = server->root_channel_data.next; c != &server->root_channel_data;
796 c = c->next) {
797 shutdown_channel(c);
798 }
799 gpr_mu_unlock(&server->mu);
800
801 server_unref(server);
802}
803
804void grpc_server_add_listener(grpc_server *server, void *arg,
ctiller58393c22015-01-07 14:03:30 -0800805 void (*start)(grpc_server *server, void *arg,
806 grpc_pollset *pollset),
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800807 void (*destroy)(grpc_server *server, void *arg)) {
808 listener *l = gpr_malloc(sizeof(listener));
809 l->arg = arg;
810 l->start = start;
811 l->destroy = destroy;
812 l->next = server->listeners;
813 server->listeners = l;
814}
815
Craig Tiller9f28ac22015-01-27 17:01:29 -0800816static grpc_call_error queue_call_request(grpc_server *server,
Craig Tiller24be0f72015-02-10 14:04:22 -0800817 requested_call *rc) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800818 call_data *calld;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800819 gpr_mu_lock(&server->mu);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800820 if (server->shutdown) {
821 gpr_mu_unlock(&server->mu);
Craig Tiller24be0f72015-02-10 14:04:22 -0800822 fail_call(server, rc);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800823 return GRPC_CALL_OK;
824 }
Craig Tiller04cc8be2015-02-10 16:11:22 -0800825 switch (rc->type) {
826 case LEGACY_CALL:
827 case BATCH_CALL:
828 calld = call_list_remove_head(&server->lists[PENDING_START], PENDING_START);
829 break;
830 case REGISTERED_CALL:
831 calld = call_list_remove_head(&rc->data.registered.registered_method->pending, PENDING_START);
832 break;
833 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800834 if (calld) {
Craig Tillercce17ac2015-01-20 09:29:28 -0800835 GPR_ASSERT(calld->state == PENDING);
Craig Tillerbb3f22f2015-01-29 16:40:56 -0800836 calld->state = ACTIVATED;
Craig Tillercce17ac2015-01-20 09:29:28 -0800837 gpr_mu_unlock(&server->mu);
Craig Tiller24be0f72015-02-10 14:04:22 -0800838 begin_call(server, calld, rc);
Craig Tillercce17ac2015-01-20 09:29:28 -0800839 return GRPC_CALL_OK;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800840 } else {
Craig Tiller24be0f72015-02-10 14:04:22 -0800841 *requested_call_array_add(&server->requested_calls) = *rc;
Craig Tillercce17ac2015-01-20 09:29:28 -0800842 gpr_mu_unlock(&server->mu);
843 return GRPC_CALL_OK;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800844 }
Craig Tillercce17ac2015-01-20 09:29:28 -0800845}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800846
Craig Tiller24be0f72015-02-10 14:04:22 -0800847grpc_call_error grpc_server_request_call(grpc_server *server, grpc_call **call,
848 grpc_call_details *details,
849 grpc_metadata_array *initial_metadata,
850 grpc_completion_queue *cq, void *tag) {
851 requested_call rc;
852 grpc_cq_begin_op(cq, NULL, GRPC_OP_COMPLETE);
853 rc.type = BATCH_CALL;
854 rc.tag = tag;
855 rc.data.batch.cq = cq;
856 rc.data.batch.call = call;
857 rc.data.batch.details = details;
858 rc.data.batch.initial_metadata = initial_metadata;
859 return queue_call_request(server, &rc);
860}
861
862grpc_call_error grpc_server_request_registered_call(
863 grpc_server *server, void *registered_method, grpc_call **call,
864 gpr_timespec *deadline, grpc_metadata_array *initial_metadata,
865 grpc_byte_buffer **optional_payload, grpc_completion_queue *cq, void *tag) {
866 requested_call rc;
867 grpc_cq_begin_op(cq, NULL, GRPC_OP_COMPLETE);
868 rc.type = REGISTERED_CALL;
869 rc.tag = tag;
870 rc.data.registered.cq = cq;
871 rc.data.registered.call = call;
872 rc.data.registered.registered_method = registered_method;
873 rc.data.registered.deadline = deadline;
874 rc.data.registered.initial_metadata = initial_metadata;
875 rc.data.registered.optional_payload = optional_payload;
876 return queue_call_request(server, &rc);
877}
878
879grpc_call_error grpc_server_request_call_old(grpc_server *server,
880 void *tag_new) {
881 requested_call rc;
882 grpc_cq_begin_op(server->cq, NULL, GRPC_SERVER_RPC_NEW);
883 rc.type = LEGACY_CALL;
884 rc.tag = tag_new;
885 return queue_call_request(server, &rc);
886}
887
888static void publish_legacy(grpc_call *call, grpc_op_error status, void *tag);
889static void publish_registered_or_batch(grpc_call *call, grpc_op_error status,
890 void *tag);
891
Craig Tiller166e2502015-02-03 20:14:41 -0800892static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) {
893 gpr_slice slice = value->slice;
894 size_t len = GPR_SLICE_LENGTH(slice);
895
896 if (len + 1 > *capacity) {
897 *capacity = GPR_MAX(len + 1, *capacity * 2);
898 *dest = gpr_realloc(*dest, *capacity);
899 }
900 memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1);
901}
902
Craig Tiller24be0f72015-02-10 14:04:22 -0800903static void begin_call(grpc_server *server, call_data *calld,
904 requested_call *rc) {
905 grpc_ioreq_completion_func publish;
906 grpc_ioreq req[2];
907 grpc_ioreq *r = req;
908
909 /* called once initial metadata has been read by the call, but BEFORE
910 the ioreq to fetch it out of the call has been executed.
911 This means metadata related fields can be relied on in calld, but to
912 fill in the metadata array passed by the client, we need to perform
913 an ioreq op, that should complete immediately. */
914
915 switch (rc->type) {
916 case LEGACY_CALL:
917 calld->legacy = gpr_malloc(sizeof(legacy_data));
918 memset(calld->legacy, 0, sizeof(legacy_data));
919 r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
920 r->data.recv_metadata = &calld->legacy->initial_metadata;
921 r++;
922 publish = publish_legacy;
923 break;
924 case BATCH_CALL:
925 cpstr(&rc->data.batch.details->host,
926 &rc->data.batch.details->host_capacity, calld->host);
927 cpstr(&rc->data.batch.details->method,
928 &rc->data.batch.details->method_capacity, calld->path);
929 grpc_call_set_completion_queue(calld->call, rc->data.batch.cq);
930 *rc->data.batch.call = calld->call;
931 r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
932 r->data.recv_metadata = rc->data.batch.initial_metadata;
933 r++;
934 publish = publish_registered_or_batch;
935 break;
936 case REGISTERED_CALL:
937 *rc->data.registered.deadline = calld->deadline;
938 grpc_call_set_completion_queue(calld->call, rc->data.registered.cq);
939 *rc->data.registered.call = calld->call;
940 r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
941 r->data.recv_metadata = rc->data.registered.initial_metadata;
942 r++;
943 if (rc->data.registered.optional_payload) {
944 r->op = GRPC_IOREQ_RECV_MESSAGE;
945 r->data.recv_message = rc->data.registered.optional_payload;
946 r++;
947 }
948 publish = publish_registered_or_batch;
949 break;
950 }
951
952 grpc_call_internal_ref(calld->call);
953 grpc_call_start_ioreq_and_call_back(calld->call, req, r - req, publish,
954 rc->tag);
955}
956
957static void fail_call(grpc_server *server, requested_call *rc) {
958 switch (rc->type) {
959 case LEGACY_CALL:
960 grpc_cq_end_new_rpc(server->cq, rc->tag, NULL, do_nothing, NULL, NULL,
961 NULL, gpr_inf_past, 0, NULL);
962 break;
963 case BATCH_CALL:
964 *rc->data.batch.call = NULL;
965 rc->data.batch.initial_metadata->count = 0;
966 grpc_cq_end_op_complete(rc->data.batch.cq, rc->tag, NULL, do_nothing,
967 NULL, GRPC_OP_ERROR);
968 break;
969 case REGISTERED_CALL:
970 *rc->data.registered.call = NULL;
971 rc->data.registered.initial_metadata->count = 0;
972 grpc_cq_end_op_complete(rc->data.registered.cq, rc->tag, NULL, do_nothing,
973 NULL, GRPC_OP_ERROR);
974 break;
975 }
976}
977
978static void publish_legacy(grpc_call *call, grpc_op_error status, void *tag) {
979 grpc_call_element *elem =
980 grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
981 call_data *calld = elem->call_data;
982 channel_data *chand = elem->channel_data;
983 grpc_server *server = chand->server;
984
985 if (status == GRPC_OP_OK) {
986 grpc_cq_end_new_rpc(server->cq, tag, call, do_nothing, NULL,
987 grpc_mdstr_as_c_string(calld->path),
988 grpc_mdstr_as_c_string(calld->host), calld->deadline,
989 calld->legacy->initial_metadata.count,
990 calld->legacy->initial_metadata.metadata);
991 } else {
992 gpr_log(GPR_ERROR, "should never reach here");
993 abort();
994 }
995}
996
997static void publish_registered_or_batch(grpc_call *call, grpc_op_error status,
998 void *tag) {
999 grpc_cq_end_op_complete(grpc_call_get_completion_queue(call), tag, call,
1000 do_nothing, NULL, status);
1001}
1002
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001003const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
1004 return server->channel_args;
1005}