|
|
|
@ -150,12 +150,15 @@ struct call_data { |
|
|
|
|
grpc_closure kill_zombie_closure; |
|
|
|
|
grpc_closure* on_done_recv_initial_metadata; |
|
|
|
|
grpc_closure recv_trailing_metadata_ready; |
|
|
|
|
grpc_error* error; |
|
|
|
|
grpc_error* recv_initial_metadata_error; |
|
|
|
|
grpc_closure* original_recv_trailing_metadata_ready; |
|
|
|
|
grpc_error* recv_trailing_metadata_error; |
|
|
|
|
bool seen_recv_trailing_metadata_ready; |
|
|
|
|
|
|
|
|
|
grpc_closure publish; |
|
|
|
|
|
|
|
|
|
call_data* pending_next; |
|
|
|
|
grpc_call_combiner* call_combiner; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct request_matcher { |
|
|
|
@ -727,21 +730,43 @@ static void server_on_recv_initial_metadata(void* ptr, grpc_error* error) { |
|
|
|
|
if (calld->host_set && calld->path_set) { |
|
|
|
|
/* do nothing */ |
|
|
|
|
} else { |
|
|
|
|
/* Pass the error reference to calld->recv_initial_metadata_error */ |
|
|
|
|
grpc_error* src_error = error; |
|
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Missing :authority or :path", &error, 1); |
|
|
|
|
"Missing :authority or :path", &src_error, 1); |
|
|
|
|
GRPC_ERROR_UNREF(src_error); |
|
|
|
|
calld->recv_initial_metadata_error = GRPC_ERROR_REF(error); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GRPC_CLOSURE_RUN(calld->on_done_recv_initial_metadata, error); |
|
|
|
|
grpc_closure* closure = calld->on_done_recv_initial_metadata; |
|
|
|
|
calld->on_done_recv_initial_metadata = nullptr; |
|
|
|
|
if (calld->seen_recv_trailing_metadata_ready) { |
|
|
|
|
GRPC_CALL_COMBINER_START(calld->call_combiner, |
|
|
|
|
&calld->recv_trailing_metadata_ready, |
|
|
|
|
calld->recv_trailing_metadata_error, |
|
|
|
|
"continue server_recv_trailing_metadata_ready"); |
|
|
|
|
} |
|
|
|
|
GRPC_CLOSURE_RUN(closure, error); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void server_recv_trailing_metadata_ready(void* user_data, |
|
|
|
|
grpc_error* err) { |
|
|
|
|
grpc_error* error) { |
|
|
|
|
grpc_call_element* elem = static_cast<grpc_call_element*>(user_data); |
|
|
|
|
call_data* calld = static_cast<call_data*>(elem->call_data); |
|
|
|
|
err = grpc_error_add_child(GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->error)); |
|
|
|
|
GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); |
|
|
|
|
if (calld->on_done_recv_initial_metadata != nullptr) { |
|
|
|
|
calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); |
|
|
|
|
calld->seen_recv_trailing_metadata_ready = true; |
|
|
|
|
GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, |
|
|
|
|
server_recv_trailing_metadata_ready, elem, |
|
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
|
GRPC_CALL_COMBINER_STOP(calld->call_combiner, |
|
|
|
|
"deferring server_recv_trailing_metadata_ready " |
|
|
|
|
"until after server_on_recv_initial_metadata"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
error = |
|
|
|
|
grpc_error_add_child(GRPC_ERROR_REF(error), |
|
|
|
|
GRPC_ERROR_REF(calld->recv_initial_metadata_error)); |
|
|
|
|
GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void server_mutate_op(grpc_call_element* elem, |
|
|
|
@ -845,6 +870,7 @@ static grpc_error* init_call_elem(grpc_call_element* elem, |
|
|
|
|
memset(calld, 0, sizeof(call_data)); |
|
|
|
|
calld->deadline = GRPC_MILLIS_INF_FUTURE; |
|
|
|
|
calld->call = grpc_call_from_top_element(elem); |
|
|
|
|
calld->call_combiner = args->call_combiner; |
|
|
|
|
|
|
|
|
|
GRPC_CLOSURE_INIT(&calld->server_on_recv_initial_metadata, |
|
|
|
|
server_on_recv_initial_metadata, elem, |
|
|
|
@ -863,7 +889,7 @@ static void destroy_call_elem(grpc_call_element* elem, |
|
|
|
|
call_data* calld = static_cast<call_data*>(elem->call_data); |
|
|
|
|
|
|
|
|
|
GPR_ASSERT(calld->state != PENDING); |
|
|
|
|
GRPC_ERROR_UNREF(calld->error); |
|
|
|
|
GRPC_ERROR_UNREF(calld->recv_initial_metadata_error); |
|
|
|
|
if (calld->host_set) { |
|
|
|
|
grpc_slice_unref_internal(calld->host); |
|
|
|
|
} |
|
|
|
|