diff options
Diffstat (limited to 'src/core/lib/surface/call.c')
-rw-r--r-- | src/core/lib/surface/call.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 74a09cf6ed..03be7bd45b 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -97,6 +97,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; @@ -105,7 +106,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 { @@ -214,9 +214,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, @@ -338,7 +338,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; @@ -684,13 +685,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)); @@ -717,7 +718,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_sched(exec_ctx, &cc->closure, GRPC_ERROR_NONE, NULL); return GRPC_CALL_OK; } @@ -753,11 +754,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"); } @@ -943,7 +944,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_sched(exec_ctx, bctl->notify_tag, bctl->error, NULL); gpr_mu_lock(&call->mu); bctl->call->used_batches = (uint8_t)(bctl->call->used_batches & @@ -951,7 +953,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); } } @@ -983,11 +986,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); @@ -1040,15 +1043,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); @@ -1056,14 +1059,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 */]; @@ -1101,7 +1104,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_sched(exec_ctx, saved_rsr_closure, error, NULL); } gpr_mu_unlock(&call->mu); @@ -1111,15 +1114,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( @@ -1165,13 +1171,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, @@ -1201,7 +1211,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); } |