|
|
|
@ -53,7 +53,8 @@ typedef enum { PENDING_START, ALL_CALLS, CALL_LIST_COUNT } call_list; |
|
|
|
|
|
|
|
|
|
typedef struct listener { |
|
|
|
|
void *arg; |
|
|
|
|
void (*start)(grpc_server *server, void *arg, grpc_pollset **pollsets, size_t pollset_count); |
|
|
|
|
void (*start)(grpc_server *server, void *arg, grpc_pollset **pollsets, |
|
|
|
|
size_t pollset_count); |
|
|
|
|
void (*destroy)(grpc_server *server, void *arg); |
|
|
|
|
struct listener *next; |
|
|
|
|
} listener; |
|
|
|
@ -129,7 +130,7 @@ struct grpc_server { |
|
|
|
|
const grpc_channel_filter **channel_filters; |
|
|
|
|
grpc_channel_args *channel_args; |
|
|
|
|
grpc_completion_queue *unregistered_cq; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grpc_completion_queue **cqs; |
|
|
|
|
grpc_pollset **pollsets; |
|
|
|
|
size_t cq_count; |
|
|
|
@ -257,11 +258,21 @@ static void server_ref(grpc_server *server) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void server_unref(grpc_server *server) { |
|
|
|
|
registered_method *rm; |
|
|
|
|
if (gpr_unref(&server->internal_refcount)) { |
|
|
|
|
grpc_channel_args_destroy(server->channel_args); |
|
|
|
|
gpr_mu_destroy(&server->mu); |
|
|
|
|
gpr_free(server->channel_filters); |
|
|
|
|
requested_call_array_destroy(&server->requested_calls); |
|
|
|
|
while ((rm = server->registered_methods) != NULL) { |
|
|
|
|
server->registered_methods = rm->next; |
|
|
|
|
gpr_free(rm->method); |
|
|
|
|
gpr_free(rm->host); |
|
|
|
|
requested_call_array_destroy(&rm->requested); |
|
|
|
|
gpr_free(rm); |
|
|
|
|
} |
|
|
|
|
gpr_free(server->cqs); |
|
|
|
|
gpr_free(server->pollsets); |
|
|
|
|
gpr_free(server); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -511,7 +522,8 @@ static void destroy_call_elem(grpc_call_element *elem) { |
|
|
|
|
if (chand->server->shutdown && chand->server->have_shutdown_tag && |
|
|
|
|
chand->server->lists[ALL_CALLS] == NULL) { |
|
|
|
|
for (i = 0; i < chand->server->cq_count; i++) { |
|
|
|
|
grpc_cq_end_server_shutdown(chand->server->cqs[i], chand->server->shutdown_tag); |
|
|
|
|
grpc_cq_end_server_shutdown(chand->server->cqs[i], |
|
|
|
|
chand->server->shutdown_tag); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&chand->server->mu); |
|
|
|
@ -547,7 +559,19 @@ static void init_channel_elem(grpc_channel_element *elem, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void destroy_channel_elem(grpc_channel_element *elem) { |
|
|
|
|
size_t i; |
|
|
|
|
channel_data *chand = elem->channel_data; |
|
|
|
|
if (chand->registered_methods) { |
|
|
|
|
for (i = 0; i < chand->registered_method_slots; i++) { |
|
|
|
|
if (chand->registered_methods[i].method) { |
|
|
|
|
grpc_mdstr_unref(chand->registered_methods[i].method); |
|
|
|
|
} |
|
|
|
|
if (chand->registered_methods[i].host) { |
|
|
|
|
grpc_mdstr_unref(chand->registered_methods[i].host); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
gpr_free(chand->registered_methods); |
|
|
|
|
} |
|
|
|
|
if (chand->server) { |
|
|
|
|
gpr_mu_lock(&chand->server->mu); |
|
|
|
|
chand->next->prev = chand->prev; |
|
|
|
@ -571,7 +595,8 @@ static void addcq(grpc_server *server, grpc_completion_queue *cq) { |
|
|
|
|
if (server->cqs[i] == cq) return; |
|
|
|
|
} |
|
|
|
|
n = server->cq_count++; |
|
|
|
|
server->cqs = gpr_realloc(server->cqs, server->cq_count * sizeof(grpc_completion_queue*)); |
|
|
|
|
server->cqs = gpr_realloc(server->cqs, |
|
|
|
|
server->cq_count * sizeof(grpc_completion_queue *)); |
|
|
|
|
server->cqs[n] = cq; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -624,7 +649,8 @@ static int streq(const char *a, const char *b) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void *grpc_server_register_method(grpc_server *server, const char *method, |
|
|
|
|
const char *host, grpc_completion_queue *cq_new_rpc) { |
|
|
|
|
const char *host, |
|
|
|
|
grpc_completion_queue *cq_new_rpc) { |
|
|
|
|
registered_method *m; |
|
|
|
|
if (!method) { |
|
|
|
|
gpr_log(GPR_ERROR, "%s method string cannot be NULL", __FUNCTION__); |
|
|
|
@ -652,7 +678,7 @@ void grpc_server_start(grpc_server *server) { |
|
|
|
|
listener *l; |
|
|
|
|
size_t i; |
|
|
|
|
|
|
|
|
|
server->pollsets = gpr_malloc(sizeof(grpc_pollset*) * server->cq_count); |
|
|
|
|
server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count); |
|
|
|
|
for (i = 0; i < server->cq_count; i++) { |
|
|
|
|
server->pollsets[i] = grpc_cq_pollset(server->cqs[i]); |
|
|
|
|
} |
|
|
|
@ -745,7 +771,7 @@ grpc_transport_setup_result grpc_server_setup_transport( |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag, |
|
|
|
|
void *shutdown_tag) { |
|
|
|
|
void *shutdown_tag) { |
|
|
|
|
listener *l; |
|
|
|
|
requested_call_array requested_calls; |
|
|
|
|
channel_data **channels; |
|
|
|
@ -781,12 +807,19 @@ static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag, |
|
|
|
|
requested_calls = server->requested_calls; |
|
|
|
|
memset(&server->requested_calls, 0, sizeof(server->requested_calls)); |
|
|
|
|
for (rm = server->registered_methods; rm; rm = rm->next) { |
|
|
|
|
if (requested_calls.count + rm->requested.count > requested_calls.capacity) { |
|
|
|
|
requested_calls.capacity = GPR_MAX(requested_calls.count + rm->requested.count, 2 * requested_calls.capacity); |
|
|
|
|
requested_calls.calls = gpr_realloc(requested_calls.calls, sizeof(*requested_calls.calls) * requested_calls.capacity); |
|
|
|
|
if (requested_calls.count + rm->requested.count > |
|
|
|
|
requested_calls.capacity) { |
|
|
|
|
requested_calls.capacity = |
|
|
|
|
GPR_MAX(requested_calls.count + rm->requested.count, |
|
|
|
|
2 * requested_calls.capacity); |
|
|
|
|
requested_calls.calls = |
|
|
|
|
gpr_realloc(requested_calls.calls, sizeof(*requested_calls.calls) * |
|
|
|
|
requested_calls.capacity); |
|
|
|
|
} |
|
|
|
|
memcpy(requested_calls.calls + requested_calls.count, rm->requested.calls, sizeof(*requested_calls.calls) * rm->requested.count); |
|
|
|
|
memcpy(requested_calls.calls + requested_calls.count, rm->requested.calls, |
|
|
|
|
sizeof(*requested_calls.calls) * rm->requested.count); |
|
|
|
|
requested_calls.count += rm->requested.count; |
|
|
|
|
gpr_free(rm->requested.calls); |
|
|
|
|
memset(&rm->requested, 0, sizeof(rm->requested)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -857,7 +890,8 @@ void grpc_server_destroy(grpc_server *server) { |
|
|
|
|
|
|
|
|
|
void grpc_server_add_listener(grpc_server *server, void *arg, |
|
|
|
|
void (*start)(grpc_server *server, void *arg, |
|
|
|
|
grpc_pollset **pollsets, size_t pollset_count), |
|
|
|
|
grpc_pollset **pollsets, |
|
|
|
|
size_t pollset_count), |
|
|
|
|
void (*destroy)(grpc_server *server, void *arg)) { |
|
|
|
|
listener *l = gpr_malloc(sizeof(listener)); |
|
|
|
|
l->arg = arg; |
|
|
|
@ -920,10 +954,9 @@ grpc_call_error grpc_server_request_call(grpc_server *server, grpc_call **call, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_call_error grpc_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_bind, |
|
|
|
|
void *tag) { |
|
|
|
|
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_bind, void *tag) { |
|
|
|
|
requested_call rc; |
|
|
|
|
registered_method *registered_method = rm; |
|
|
|
|
grpc_cq_begin_op(registered_method->cq, NULL, GRPC_OP_COMPLETE); |
|
|
|
@ -1025,20 +1058,20 @@ static void begin_call(grpc_server *server, call_data *calld, |
|
|
|
|
static void fail_call(grpc_server *server, requested_call *rc) { |
|
|
|
|
switch (rc->type) { |
|
|
|
|
case LEGACY_CALL: |
|
|
|
|
grpc_cq_end_new_rpc(server->unregistered_cq, rc->tag, NULL, do_nothing, NULL, NULL, |
|
|
|
|
NULL, gpr_inf_past, 0, NULL); |
|
|
|
|
grpc_cq_end_new_rpc(server->unregistered_cq, rc->tag, NULL, do_nothing, |
|
|
|
|
NULL, NULL, NULL, gpr_inf_past, 0, NULL); |
|
|
|
|
break; |
|
|
|
|
case BATCH_CALL: |
|
|
|
|
*rc->data.batch.call = NULL; |
|
|
|
|
rc->data.batch.initial_metadata->count = 0; |
|
|
|
|
grpc_cq_end_op_complete(server->unregistered_cq, rc->tag, NULL, do_nothing, NULL, |
|
|
|
|
GRPC_OP_ERROR); |
|
|
|
|
grpc_cq_end_op_complete(server->unregistered_cq, rc->tag, NULL, |
|
|
|
|
do_nothing, NULL, GRPC_OP_ERROR); |
|
|
|
|
break; |
|
|
|
|
case REGISTERED_CALL: |
|
|
|
|
*rc->data.registered.call = NULL; |
|
|
|
|
rc->data.registered.initial_metadata->count = 0; |
|
|
|
|
grpc_cq_end_op_complete(rc->data.registered.registered_method->cq, rc->tag, NULL, do_nothing, NULL, |
|
|
|
|
GRPC_OP_ERROR); |
|
|
|
|
grpc_cq_end_op_complete(rc->data.registered.registered_method->cq, |
|
|
|
|
rc->tag, NULL, do_nothing, NULL, GRPC_OP_ERROR); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|