diff options
Diffstat (limited to 'src/core/lib/surface')
-rw-r--r-- | src/core/lib/surface/alarm.c | 4 | ||||
-rw-r--r-- | src/core/lib/surface/call.c | 60 | ||||
-rw-r--r-- | src/core/lib/surface/channel.c | 7 | ||||
-rw-r--r-- | src/core/lib/surface/channel_ping.c | 6 | ||||
-rw-r--r-- | src/core/lib/surface/completion_queue.c | 62 | ||||
-rw-r--r-- | src/core/lib/surface/completion_queue.h | 2 | ||||
-rw-r--r-- | src/core/lib/surface/init_secure.c | 8 | ||||
-rw-r--r-- | src/core/lib/surface/lame_client.c | 13 | ||||
-rw-r--r-- | src/core/lib/surface/server.c | 117 |
9 files changed, 176 insertions, 103 deletions
diff --git a/src/core/lib/surface/alarm.c b/src/core/lib/surface/alarm.c index 2cf2f00b31..aa9d60ee6a 100644 --- a/src/core/lib/surface/alarm.c +++ b/src/core/lib/surface/alarm.c @@ -48,9 +48,9 @@ struct grpc_alarm { static void do_nothing_end_completion(grpc_exec_ctx *exec_ctx, void *arg, grpc_cq_completion *c) {} -static void alarm_cb(grpc_exec_ctx *exec_ctx, void *arg, bool success) { +static void alarm_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_alarm *alarm = arg; - grpc_cq_end_op(exec_ctx, alarm->cq, alarm->tag, success, + grpc_cq_end_op(exec_ctx, alarm->cq, alarm->tag, error, do_nothing_end_completion, NULL, &alarm->completion); } diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index c8728fa278..3915ba57a2 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -122,6 +122,7 @@ typedef struct batch_control { grpc_closure finish_batch; void *notify_tag; gpr_refcount steps_to_complete; + grpc_error *error; uint8_t send_initial_metadata; uint8_t send_message; @@ -130,7 +131,6 @@ typedef struct batch_control { uint8_t recv_message; uint8_t recv_final_op; uint8_t is_notify_tag_closure; - uint8_t success; } batch_control; struct grpc_call { @@ -239,9 +239,9 @@ static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c, grpc_status_code status, const char *description); static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack, - bool success); + grpc_error *error); static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, - bool success); + grpc_error *error); grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, @@ -363,7 +363,8 @@ void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) { GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON); } -static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, bool success) { +static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, + grpc_error *error) { size_t i; int ii; grpc_call *c = call; @@ -709,13 +710,13 @@ typedef struct cancel_closure { grpc_status_code status; } cancel_closure; -static void done_cancel(grpc_exec_ctx *exec_ctx, void *ccp, bool success) { +static void done_cancel(grpc_exec_ctx *exec_ctx, void *ccp, grpc_error *error) { cancel_closure *cc = ccp; GRPC_CALL_INTERNAL_UNREF(exec_ctx, cc->call, "cancel"); gpr_free(cc); } -static void send_cancel(grpc_exec_ctx *exec_ctx, void *ccp, bool success) { +static void send_cancel(grpc_exec_ctx *exec_ctx, void *ccp, grpc_error *error) { grpc_transport_stream_op op; cancel_closure *cc = ccp; memset(&op, 0, sizeof(op)); @@ -742,7 +743,7 @@ static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c, cc->call = c; cc->status = status; GRPC_CALL_INTERNAL_REF(c, "cancel"); - grpc_exec_ctx_enqueue(exec_ctx, &cc->closure, true, NULL); + grpc_exec_ctx_push(exec_ctx, &cc->closure, GRPC_ERROR_NONE, NULL); return GRPC_CALL_OK; } @@ -778,11 +779,11 @@ grpc_call *grpc_call_from_top_element(grpc_call_element *elem) { return CALL_FROM_TOP_ELEM(elem); } -static void call_alarm(grpc_exec_ctx *exec_ctx, void *arg, bool success) { +static void call_alarm(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_call *call = arg; gpr_mu_lock(&call->mu); call->have_alarm = 0; - if (success) { + if (error != GRPC_ERROR_CANCELLED) { cancel_with_status(exec_ctx, call, GRPC_STATUS_DEADLINE_EXCEEDED, "Deadline Exceeded"); } @@ -968,7 +969,8 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx, batch_control *bctl) { grpc_call *call = bctl->call; if (bctl->is_notify_tag_closure) { - grpc_exec_ctx_enqueue(exec_ctx, bctl->notify_tag, bctl->success, NULL); + /* unrefs bctl->error */ + grpc_exec_ctx_push(exec_ctx, bctl->notify_tag, bctl->error, NULL); gpr_mu_lock(&call->mu); bctl->call->used_batches = (uint8_t)(bctl->call->used_batches & @@ -976,7 +978,8 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx, gpr_mu_unlock(&call->mu); GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion"); } else { - grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, bctl->success, + /* unrefs bctl->error */ + grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, bctl->error, finish_batch_completion, bctl, &bctl->cq_completion); } } @@ -1008,11 +1011,11 @@ static void continue_receiving_slices(grpc_exec_ctx *exec_ctx, } static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, - bool success) { + grpc_error *error) { batch_control *bctl = bctlp; grpc_call *call = bctl->call; - if (success) { + if (error == GRPC_ERROR_NONE) { gpr_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer, call->receiving_slice); continue_receiving_slices(exec_ctx, bctl); @@ -1065,15 +1068,15 @@ static void process_data_after_md(grpc_exec_ctx *exec_ctx, batch_control *bctl, } static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp, - bool success) { + grpc_error *error) { batch_control *bctl = bctlp; grpc_call *call = bctl->call; gpr_mu_lock(&bctl->call->mu); - if (bctl->call->has_initial_md_been_received || !success || + if (bctl->call->has_initial_md_been_received || error != GRPC_ERROR_NONE || call->receiving_stream == NULL) { gpr_mu_unlock(&bctl->call->mu); - process_data_after_md(exec_ctx, bctlp, success); + process_data_after_md(exec_ctx, bctlp, error); } else { call->saved_receiving_stream_ready_bctlp = bctlp; gpr_mu_unlock(&bctl->call->mu); @@ -1081,14 +1084,14 @@ static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp, } static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, - void *bctlp, bool success) { + void *bctlp, grpc_error *error) { batch_control *bctl = bctlp; grpc_call *call = bctl->call; gpr_mu_lock(&call->mu); - if (!success) { - bctl->success = false; + if (error != GRPC_ERROR_NONE) { + bctl->error = GRPC_ERROR_REF(error); } else { grpc_metadata_batch *md = &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; @@ -1126,7 +1129,7 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, grpc_closure *saved_rsr_closure = grpc_closure_create( receiving_stream_ready, call->saved_receiving_stream_ready_bctlp); call->saved_receiving_stream_ready_bctlp = NULL; - grpc_exec_ctx_enqueue(exec_ctx, saved_rsr_closure, success, NULL); + grpc_exec_ctx_push(exec_ctx, saved_rsr_closure, error, NULL); } gpr_mu_unlock(&call->mu); @@ -1136,15 +1139,18 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, } } -static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, bool success) { +static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, + grpc_error *error) { batch_control *bctl = bctlp; grpc_call *call = bctl->call; grpc_call *child_call; grpc_call *next_child_call; + GRPC_ERROR_REF(error); + gpr_mu_lock(&call->mu); if (bctl->send_initial_metadata) { - if (!success) { + if (error != GRPC_ERROR_NONE) { set_status_code(call, STATUS_FROM_CORE, GRPC_STATUS_UNAVAILABLE); } grpc_metadata_batch_destroy( @@ -1190,13 +1196,17 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, bool success) { call->final_op.server.cancelled); } - success = 1; + GRPC_ERROR_UNREF(error); + error = GRPC_ERROR_NONE; } - bctl->success = success != 0; + GRPC_ERROR_UNREF(bctl->error); + bctl->error = GRPC_ERROR_REF(error); gpr_mu_unlock(&call->mu); if (gpr_unref(&bctl->steps_to_complete)) { post_batch_completion(exec_ctx, bctl); } + + GRPC_ERROR_UNREF(error); } static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, @@ -1226,7 +1236,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, if (nops == 0) { GRPC_CALL_INTERNAL_REF(call, "completion"); - bctl->success = 1; + bctl->error = GRPC_ERROR_NONE; if (!is_notify_tag_closure) { grpc_cq_begin_op(call->cq, notify_tag); } diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c index b6b760b5d8..3c68dc0c4b 100644 --- a/src/core/lib/surface/channel.c +++ b/src/core/lib/surface/channel.c @@ -80,7 +80,8 @@ struct grpc_channel { /* the protobuf library will (by default) start warning at 100megs */ #define DEFAULT_MAX_MESSAGE_LENGTH (100 * 1024 * 1024) -static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, bool success); +static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error); grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, const grpc_channel_args *input_args, @@ -267,7 +268,7 @@ void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, } static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_success) { + grpc_error *error) { grpc_channel *channel = arg; grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(channel)); while (channel->registered_calls) { @@ -293,7 +294,7 @@ void grpc_channel_destroy(grpc_channel *channel) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_API_TRACE("grpc_channel_destroy(channel=%p)", 1, (channel)); memset(&op, 0, sizeof(op)); - op.disconnect = 1; + op.disconnect_with_error = GRPC_ERROR_CREATE("Channel Destroyed"); elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0); elem->filter->start_transport_op(&exec_ctx, elem, &op); diff --git a/src/core/lib/surface/channel_ping.c b/src/core/lib/surface/channel_ping.c index 5a50698695..9818f9d2f2 100644 --- a/src/core/lib/surface/channel_ping.c +++ b/src/core/lib/surface/channel_ping.c @@ -53,10 +53,10 @@ static void ping_destroy(grpc_exec_ctx *exec_ctx, void *arg, gpr_free(arg); } -static void ping_done(grpc_exec_ctx *exec_ctx, void *arg, bool success) { +static void ping_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { ping_result *pr = arg; - grpc_cq_end_op(exec_ctx, pr->cq, pr->tag, success, ping_destroy, pr, - &pr->completion_storage); + grpc_cq_end_op(exec_ctx, pr->cq, pr->tag, GRPC_ERROR_REF(error), ping_destroy, + pr, &pr->completion_storage); } void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq, diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 5eb7cf1bf4..ecc127876b 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -92,7 +92,7 @@ static gpr_mu g_freelist_mu; static grpc_completion_queue *g_freelist; static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *cc, - bool success); + grpc_error *error); void grpc_cq_global_init(void) { gpr_mu_init(&g_freelist_mu); } @@ -176,7 +176,7 @@ void grpc_cq_internal_ref(grpc_completion_queue *cc) { } static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *arg, - bool success) { + grpc_error *error) { grpc_completion_queue *cc = arg; GRPC_CQ_INTERNAL_UNREF(cc, "pollset_destroy"); } @@ -219,7 +219,7 @@ void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag) { event, then enter shutdown mode */ /* Queue a GRPC_OP_COMPLETED operation */ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, - void *tag, int success, + void *tag, grpc_error *error, void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg, grpc_cq_completion *storage), void *done_arg, grpc_cq_completion *storage) { @@ -231,16 +231,20 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, #endif GPR_TIMER_BEGIN("grpc_cq_end_op", 0); - GRPC_API_TRACE( - "grpc_cq_end_op(exec_ctx=%p, cc=%p, tag=%p, success=%d, done=%p, " - "done_arg=%p, storage=%p)", - 7, (exec_ctx, cc, tag, success, done, done_arg, storage)); + if (grpc_api_trace) { + const char *errmsg = grpc_error_string(error); + GRPC_API_TRACE( + "grpc_cq_end_op(exec_ctx=%p, cc=%p, tag=%p, error=%s, done=%p, " + "done_arg=%p, storage=%p)", + 7, (exec_ctx, cc, tag, errmsg, done, done_arg, storage)); + grpc_error_free_string(errmsg); + } storage->tag = tag; storage->done = done; storage->done_arg = done_arg; - storage->next = - ((uintptr_t)&cc->completed_head) | ((uintptr_t)(success != 0)); + storage->next = ((uintptr_t)&cc->completed_head) | + ((uintptr_t)(error == GRPC_ERROR_NONE)); gpr_mu_lock(cc->mu); #ifndef NDEBUG @@ -267,8 +271,15 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, break; } } - grpc_pollset_kick(POLLSET_FROM_CQ(cc), pluck_worker); + grpc_error *kick_error = + grpc_pollset_kick(POLLSET_FROM_CQ(cc), pluck_worker); gpr_mu_unlock(cc->mu); + if (kick_error != GRPC_ERROR_NONE) { + const char *msg = grpc_error_string(kick_error); + gpr_log(GPR_ERROR, "Kick failed: %s", msg); + grpc_error_free_string(msg); + GRPC_ERROR_UNREF(kick_error); + } } else { cc->completed_tail->next = ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next); @@ -282,6 +293,8 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, } GPR_TIMER_END("grpc_cq_end_op", 0); + + GRPC_ERROR_UNREF(error); } grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, @@ -347,8 +360,18 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, gpr_mu_lock(cc->mu); continue; } else { - grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, - iteration_deadline); + grpc_error *err = grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), + &worker, now, iteration_deadline); + if (err != GRPC_ERROR_NONE) { + gpr_mu_unlock(cc->mu); + const char *msg = grpc_error_string(err); + gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg); + grpc_error_free_string(msg); + GRPC_ERROR_UNREF(err); + memset(&ret, 0, sizeof(ret)); + ret.type = GRPC_QUEUE_TIMEOUT; + break; + } } } GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret); @@ -464,8 +487,19 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, grpc_exec_ctx_flush(&exec_ctx); gpr_mu_lock(cc->mu); } else { - grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, - iteration_deadline); + grpc_error *err = grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), + &worker, now, iteration_deadline); + if (err != GRPC_ERROR_NONE) { + del_plucker(cc, tag, &worker); + gpr_mu_unlock(cc->mu); + const char *msg = grpc_error_string(err); + gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg); + grpc_error_free_string(msg); + GRPC_ERROR_UNREF(err); + memset(&ret, 0, sizeof(ret)); + ret.type = GRPC_QUEUE_TIMEOUT; + break; + } } del_plucker(cc, tag, &worker); } diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 3d0dd13c53..a866858cb5 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -75,7 +75,7 @@ void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag); /* Queue a GRPC_OP_COMPLETED operation; tag must correspond to the tag passed to grpc_cq_begin_op */ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, - void *tag, int success, + void *tag, grpc_error *error, void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg, grpc_cq_completion *storage), void *done_arg, grpc_cq_completion *storage); diff --git a/src/core/lib/surface/init_secure.c b/src/core/lib/surface/init_secure.c index 3fda2c9e1e..7ee7b51568 100644 --- a/src/core/lib/surface/init_secure.c +++ b/src/core/lib/surface/init_secure.c @@ -37,10 +37,10 @@ #include <string.h> #include "src/core/lib/debug/trace.h" -#include "src/core/lib/security/auth_filters.h" -#include "src/core/lib/security/credentials.h" -#include "src/core/lib/security/secure_endpoint.h" -#include "src/core/lib/security/security_connector.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/transport/auth_filters.h" +#include "src/core/lib/security/transport/secure_endpoint.h" +#include "src/core/lib/security/transport/security_connector.h" #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/tsi/transport_security_interface.h" diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c index f50ec54cea..5c15b676f8 100644 --- a/src/core/lib/surface/lame_client.c +++ b/src/core/lib/surface/lame_client.c @@ -80,7 +80,8 @@ static void lame_start_transport_stream_op(grpc_exec_ctx *exec_ctx, } else if (op->recv_trailing_metadata != NULL) { fill_metadata(elem, op->recv_trailing_metadata); } - grpc_transport_stream_op_finish_with_failure(exec_ctx, op); + grpc_transport_stream_op_finish_with_failure( + exec_ctx, op, GRPC_ERROR_CREATE("lame client channel")); } static char *lame_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { @@ -93,15 +94,17 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx, if (op->on_connectivity_state_change) { GPR_ASSERT(*op->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE); *op->connectivity_state = GRPC_CHANNEL_FATAL_FAILURE; - op->on_connectivity_state_change->cb( - exec_ctx, op->on_connectivity_state_change->cb_arg, 1); + grpc_exec_ctx_push(exec_ctx, op->on_connectivity_state_change, + GRPC_ERROR_NONE, NULL); } if (op->on_consumed != NULL) { - op->on_consumed->cb(exec_ctx, op->on_consumed->cb_arg, 1); + grpc_exec_ctx_push(exec_ctx, op->on_consumed, GRPC_ERROR_NONE, NULL); } if (op->send_ping != NULL) { - op->send_ping->cb(exec_ctx, op->send_ping->cb_arg, 0); + grpc_exec_ctx_push(exec_ctx, op->send_ping, + GRPC_ERROR_CREATE("lame client channel"), NULL); } + GRPC_ERROR_UNREF(op->disconnect_with_error); } static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 4d179d0ab1..740e072898 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -236,9 +236,11 @@ struct grpc_server { #define SERVER_FROM_CALL_ELEM(elem) \ (((channel_data *)(elem)->channel_data)->server) -static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *calld, bool success); +static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *calld, + grpc_error *error); static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, - size_t cq_idx, requested_call *rc); + size_t cq_idx, requested_call *rc, grpc_error *error); + /* Before calling maybe_finish_shutdown, we must hold mu_global and not hold mu_call */ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server); @@ -269,14 +271,14 @@ struct shutdown_cleanup_args { }; static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg, - bool iomgr_status_ignored) { + grpc_error *error) { struct shutdown_cleanup_args *a = arg; gpr_slice_unref(a->slice); gpr_free(a); } static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, - int send_goaway, int send_disconnect) { + int send_goaway, grpc_error *send_disconnect) { grpc_transport_op op; struct shutdown_cleanup_args *sc; grpc_channel_element *elem; @@ -287,7 +289,7 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, sc->slice = gpr_slice_from_copied_string("Server shutdown"); op.goaway_message = &sc->slice; op.goaway_status = GRPC_STATUS_OK; - op.disconnect = send_disconnect; + op.disconnect_with_error = send_disconnect; grpc_closure_init(&sc->closure, shutdown_cleanup, sc); op.on_consumed = &sc->closure; @@ -298,14 +300,16 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx, channel_broadcaster *cb, int send_goaway, - int force_disconnect) { + grpc_error *force_disconnect) { size_t i; for (i = 0; i < cb->num_channels; i++) { - send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect); + send_shutdown(exec_ctx, cb->channels[i], send_goaway, + GRPC_ERROR_REF(force_disconnect)); GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast"); } gpr_free(cb->channels); + GRPC_ERROR_UNREF(force_disconnect); } /* @@ -325,7 +329,8 @@ static void request_matcher_destroy(request_matcher *rm) { gpr_stack_lockfree_destroy(rm->requests); } -static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, bool success) { +static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, + grpc_error *error) { grpc_call_destroy(grpc_call_from_top_element(elem)); } @@ -340,18 +345,21 @@ static void request_matcher_zombify_all_pending_calls(grpc_exec_ctx *exec_ctx, grpc_closure_init( &calld->kill_zombie_closure, kill_zombie, grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0)); - grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); + grpc_exec_ctx_push(exec_ctx, &calld->kill_zombie_closure, GRPC_ERROR_NONE, + NULL); } } static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx, grpc_server *server, - request_matcher *rm) { + request_matcher *rm, + grpc_error *error) { int request_id; while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) { fail_call(exec_ctx, server, rm->cq_idx, - &server->requested_calls[request_id]); + &server->requested_calls[request_id], GRPC_ERROR_REF(error)); } + GRPC_ERROR_UNREF(error); } /* @@ -412,7 +420,7 @@ static void orphan_channel(channel_data *chand) { } static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd, - bool success) { + grpc_error *error) { channel_data *chand = cd; grpc_server *server = chand->server; GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server"); @@ -501,23 +509,24 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server, grpc_call_stack_element(grpc_call_get_call_stack(call), 0); channel_data *chand = elem->channel_data; server_ref(chand->server); - grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, true, done_request_event, rc, - &rc->completion); + grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, GRPC_ERROR_NONE, + done_request_event, rc, &rc->completion); } -static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg, bool success) { +static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { call_data *calld = arg; request_matcher *rm = calld->request_matcher; grpc_server *server = rm->server; - if (!success || gpr_atm_acq_load(&server->shutdown_flag)) { + if (error != GRPC_ERROR_NONE || gpr_atm_acq_load(&server->shutdown_flag)) { gpr_mu_lock(&calld->mu_state); calld->state = ZOMBIED; gpr_mu_unlock(&calld->mu_state); grpc_closure_init( &calld->kill_zombie_closure, kill_zombie, grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0)); - grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); + grpc_exec_ctx_push(exec_ctx, &calld->kill_zombie_closure, error, NULL); return; } @@ -555,7 +564,8 @@ static void finish_start_new_rpc( calld->state = ZOMBIED; gpr_mu_unlock(&calld->mu_state); grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem); - grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); + grpc_exec_ctx_push(exec_ctx, &calld->kill_zombie_closure, GRPC_ERROR_NONE, + NULL); return; } @@ -563,7 +573,7 @@ static void finish_start_new_rpc( switch (payload_handling) { case GRPC_SRM_PAYLOAD_NONE: - publish_new_rpc(exec_ctx, calld, true); + publish_new_rpc(exec_ctx, calld, GRPC_ERROR_NONE); break; case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: { grpc_op op; @@ -653,22 +663,24 @@ static int num_channels(grpc_server *server) { } static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx, - grpc_server *server) { + grpc_server *server, grpc_error *error) { if (server->started) { for (size_t i = 0; i < server->cq_count; i++) { request_matcher_kill_requests(exec_ctx, server, - &server->unregistered_request_matchers[i]); + &server->unregistered_request_matchers[i], + GRPC_ERROR_REF(error)); request_matcher_zombify_all_pending_calls( exec_ctx, &server->unregistered_request_matchers[i]); for (registered_method *rm = server->registered_methods; rm; rm = rm->next) { - request_matcher_kill_requests(exec_ctx, server, - &rm->request_matchers[i]); + request_matcher_kill_requests( + exec_ctx, server, &rm->request_matchers[i], GRPC_ERROR_REF(error)); request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matchers[i]); } } } + GRPC_ERROR_UNREF(error); } static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, @@ -678,7 +690,8 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, return; } - kill_pending_work_locked(exec_ctx, server); + kill_pending_work_locked(exec_ctx, server, + GRPC_ERROR_CREATE("Server Shutdown")); if (server->root_channel_data.next != &server->root_channel_data || server->listeners_destroyed < num_listeners(server)) { @@ -699,7 +712,8 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, for (i = 0; i < server->num_shutdown_tags; i++) { server_ref(server); 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].tag, GRPC_ERROR_NONE, + done_shutdown_event, server, &server->shutdown_tags[i].completion); } } @@ -722,11 +736,12 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { } static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, - bool success) { + grpc_error *error) { grpc_call_element *elem = ptr; call_data *calld = elem->call_data; gpr_timespec op_deadline; + GRPC_ERROR_REF(error); grpc_metadata_batch_filter(calld->recv_initial_metadata, server_filter, elem); op_deadline = calld->recv_initial_metadata->deadline; if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) { @@ -735,11 +750,13 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, if (calld->host && calld->path) { /* do nothing */ } else { - success = 0; + GRPC_ERROR_UNREF(error); + error = + GRPC_ERROR_CREATE_REFERENCING("Missing :authority or :path", &error, 1); } - calld->on_done_recv_initial_metadata->cb( - exec_ctx, calld->on_done_recv_initial_metadata->cb_arg, success); + grpc_exec_ctx_push(exec_ctx, calld->on_done_recv_initial_metadata, error, + NULL); } static void server_mutate_op(grpc_call_element *elem, @@ -764,10 +781,10 @@ static void server_start_transport_stream_op(grpc_exec_ctx *exec_ctx, } static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, - bool success) { + grpc_error *error) { grpc_call_element *elem = ptr; call_data *calld = elem->call_data; - if (success) { + if (error == GRPC_ERROR_NONE) { start_new_rpc(exec_ctx, elem); } else { gpr_mu_lock(&calld->mu_state); @@ -775,7 +792,8 @@ static void got_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, calld->state = ZOMBIED; gpr_mu_unlock(&calld->mu_state); grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem); - grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); + grpc_exec_ctx_push(exec_ctx, &calld->kill_zombie_closure, GRPC_ERROR_NONE, + NULL); } else if (calld->state == PENDING) { calld->state = ZOMBIED; gpr_mu_unlock(&calld->mu_state); @@ -808,7 +826,7 @@ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd, } static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd, - bool iomgr_status_ignored) { + grpc_error *error) { channel_data *chand = cd; grpc_server *server = chand->server; if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) { @@ -1152,7 +1170,9 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s, op.set_accept_stream_user_data = chand; op.on_connectivity_state_change = &chand->channel_connectivity_changed; op.connectivity_state = &chand->connectivity_state; - op.disconnect = gpr_atm_acq_load(&s->shutdown_flag) != 0; + if (gpr_atm_acq_load(&s->shutdown_flag) != 0) { + op.disconnect_with_error = GRPC_ERROR_CREATE("Server shutdown"); + } grpc_transport_perform_op(exec_ctx, transport, &op); } @@ -1163,7 +1183,7 @@ void done_published_shutdown(grpc_exec_ctx *exec_ctx, void *done_arg, } static void listener_destroy_done(grpc_exec_ctx *exec_ctx, void *s, - bool success) { + grpc_error *error) { grpc_server *server = s; gpr_mu_lock(&server->mu_global); server->listeners_destroyed++; @@ -1185,8 +1205,8 @@ void grpc_server_shutdown_and_notify(grpc_server *server, gpr_mu_lock(&server->mu_global); grpc_cq_begin_op(cq, tag); if (server->shutdown_published) { - grpc_cq_end_op(&exec_ctx, cq, tag, 1, done_published_shutdown, NULL, - gpr_malloc(sizeof(grpc_cq_completion))); + grpc_cq_end_op(&exec_ctx, cq, tag, GRPC_ERROR_NONE, done_published_shutdown, + NULL, gpr_malloc(sizeof(grpc_cq_completion))); gpr_mu_unlock(&server->mu_global); goto done; } @@ -1209,7 +1229,8 @@ void grpc_server_shutdown_and_notify(grpc_server *server, /* collect all unregistered then registered calls */ gpr_mu_lock(&server->mu_call); - kill_pending_work_locked(&exec_ctx, server); + kill_pending_work_locked(&exec_ctx, server, + GRPC_ERROR_CREATE("Server Shutdown")); gpr_mu_unlock(&server->mu_call); maybe_finish_shutdown(&exec_ctx, server); @@ -1237,7 +1258,8 @@ void grpc_server_cancel_all_calls(grpc_server *server) { channel_broadcaster_init(server, &broadcaster); gpr_mu_unlock(&server->mu_global); - channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, 1); + channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, + GRPC_ERROR_CREATE("Cancelling all calls")); grpc_exec_ctx_finish(&exec_ctx); } @@ -1284,13 +1306,15 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx, request_matcher *rm = NULL; int request_id; if (gpr_atm_acq_load(&server->shutdown_flag)) { - fail_call(exec_ctx, server, cq_idx, rc); + fail_call(exec_ctx, server, cq_idx, rc, + GRPC_ERROR_CREATE("Server Shutdown")); return GRPC_CALL_OK; } request_id = gpr_stack_lockfree_pop(server->request_freelist); if (request_id == -1) { /* out of request ids: just fail this one */ - fail_call(exec_ctx, server, cq_idx, rc); + fail_call(exec_ctx, server, cq_idx, rc, + GRPC_ERROR_CREATE("Server Shutdown")); return GRPC_CALL_OK; } switch (rc->type) { @@ -1318,8 +1342,8 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx, grpc_closure_init( &calld->kill_zombie_closure, kill_zombie, grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0)); - grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, - NULL); + grpc_exec_ctx_push(exec_ctx, &calld->kill_zombie_closure, + GRPC_ERROR_NONE, NULL); } else { GPR_ASSERT(calld->state == PENDING); calld->state = ACTIVATED; @@ -1425,13 +1449,14 @@ done: } static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, - size_t cq_idx, requested_call *rc) { + size_t cq_idx, requested_call *rc, grpc_error *error) { *rc->call = NULL; rc->initial_metadata->count = 0; + GPR_ASSERT(error != GRPC_ERROR_NONE); server_ref(server); - grpc_cq_end_op(exec_ctx, server->cqs[cq_idx], rc->tag, 0, done_request_event, - rc, &rc->completion); + grpc_cq_end_op(exec_ctx, server->cqs[cq_idx], rc->tag, error, + done_request_event, rc, &rc->completion); } const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) { |