diff options
author | Yash Tibrewal <yashkt@google.com> | 2018-09-21 10:59:44 -0700 |
---|---|---|
committer | Yash Tibrewal <yashkt@google.com> | 2018-09-21 10:59:44 -0700 |
commit | a12740f0ae20cbead056df8c2231052c218d0d02 (patch) | |
tree | 049ee16841c5c071c95bc2ad83871ef93f073e99 /src/core/lib/surface | |
parent | 4e7ede8dd21e831362547c1ba46607b9b0f81b76 (diff) |
Revert the revert to server.cc
Diffstat (limited to 'src/core/lib/surface')
-rw-r--r-- | src/core/lib/surface/server.cc | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 5fa58ffdec..72ddc2648d 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -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); } |