|
|
@ -239,7 +239,6 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { |
|
|
|
// ContextList::Execute follows semantics of a callback function and does not
|
|
|
|
// ContextList::Execute follows semantics of a callback function and does not
|
|
|
|
// take a ref on error
|
|
|
|
// take a ref on error
|
|
|
|
grpc_core::ContextList::Execute(cl, nullptr, error); |
|
|
|
grpc_core::ContextList::Execute(cl, nullptr, error); |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
cl = nullptr; |
|
|
|
cl = nullptr; |
|
|
|
|
|
|
|
|
|
|
|
grpc_slice_buffer_destroy(&read_buffer); |
|
|
|
grpc_slice_buffer_destroy(&read_buffer); |
|
|
@ -250,8 +249,6 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { |
|
|
|
GPR_ASSERT(lists[i].tail == nullptr); |
|
|
|
GPR_ASSERT(lists[i].tail == nullptr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GRPC_ERROR_UNREF(goaway_error); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GPR_ASSERT(grpc_chttp2_stream_map_size(&stream_map) == 0); |
|
|
|
GPR_ASSERT(grpc_chttp2_stream_map_size(&stream_map) == 0); |
|
|
|
|
|
|
|
|
|
|
|
grpc_chttp2_stream_map_destroy(&stream_map); |
|
|
|
grpc_chttp2_stream_map_destroy(&stream_map); |
|
|
@ -267,7 +264,6 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { |
|
|
|
write_cb_pool = next; |
|
|
|
write_cb_pool = next; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GRPC_ERROR_UNREF(closed_with_error); |
|
|
|
|
|
|
|
gpr_free(ping_acks); |
|
|
|
gpr_free(ping_acks); |
|
|
|
if (grpc_core::test_only_destruct_callback != nullptr) { |
|
|
|
if (grpc_core::test_only_destruct_callback != nullptr) { |
|
|
|
grpc_core::test_only_destruct_callback(); |
|
|
|
grpc_core::test_only_destruct_callback(); |
|
|
@ -559,15 +555,15 @@ static void destroy_transport(grpc_transport* gt) { |
|
|
|
|
|
|
|
|
|
|
|
static void close_transport_locked(grpc_chttp2_transport* t, |
|
|
|
static void close_transport_locked(grpc_chttp2_transport* t, |
|
|
|
grpc_error_handle error) { |
|
|
|
grpc_error_handle error) { |
|
|
|
end_all_the_calls(t, GRPC_ERROR_REF(error)); |
|
|
|
end_all_the_calls(t, error); |
|
|
|
cancel_pings(t, GRPC_ERROR_REF(error)); |
|
|
|
cancel_pings(t, error); |
|
|
|
if (GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
if (t->closed_with_error.ok()) { |
|
|
|
if (!grpc_error_has_clear_grpc_status(error)) { |
|
|
|
if (!grpc_error_has_clear_grpc_status(error)) { |
|
|
|
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, |
|
|
|
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, |
|
|
|
GRPC_STATUS_UNAVAILABLE); |
|
|
|
GRPC_STATUS_UNAVAILABLE); |
|
|
|
} |
|
|
|
} |
|
|
|
if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) { |
|
|
|
if (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE) { |
|
|
|
if (GRPC_ERROR_IS_NONE(t->close_transport_on_writes_finished)) { |
|
|
|
if (t->close_transport_on_writes_finished.ok()) { |
|
|
|
t->close_transport_on_writes_finished = |
|
|
|
t->close_transport_on_writes_finished = |
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
"Delayed close due to in-progress write"); |
|
|
|
"Delayed close due to in-progress write"); |
|
|
@ -576,8 +572,8 @@ static void close_transport_locked(grpc_chttp2_transport* t, |
|
|
|
grpc_error_add_child(t->close_transport_on_writes_finished, error); |
|
|
|
grpc_error_add_child(t->close_transport_on_writes_finished, error); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
GPR_ASSERT(!GRPC_ERROR_IS_NONE(error)); |
|
|
|
GPR_ASSERT(!error.ok()); |
|
|
|
t->closed_with_error = GRPC_ERROR_REF(error); |
|
|
|
t->closed_with_error = error; |
|
|
|
connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, absl::Status(), |
|
|
|
connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, absl::Status(), |
|
|
|
"close_transport"); |
|
|
|
"close_transport"); |
|
|
|
if (t->ping_state.is_delayed_ping_timer_set) { |
|
|
|
if (t->ping_state.is_delayed_ping_timer_set) { |
|
|
@ -606,19 +602,17 @@ static void close_transport_locked(grpc_chttp2_transport* t, |
|
|
|
GRPC_CHTTP2_STREAM_UNREF(s, "chttp2_writing:close"); |
|
|
|
GRPC_CHTTP2_STREAM_UNREF(s, "chttp2_writing:close"); |
|
|
|
} |
|
|
|
} |
|
|
|
GPR_ASSERT(t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE); |
|
|
|
GPR_ASSERT(t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE); |
|
|
|
grpc_endpoint_shutdown(t->ep, GRPC_ERROR_REF(error)); |
|
|
|
grpc_endpoint_shutdown(t->ep, error); |
|
|
|
} |
|
|
|
} |
|
|
|
if (t->notify_on_receive_settings != nullptr) { |
|
|
|
if (t->notify_on_receive_settings != nullptr) { |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, t->notify_on_receive_settings, |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, t->notify_on_receive_settings, |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
t->notify_on_receive_settings = nullptr; |
|
|
|
t->notify_on_receive_settings = nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
if (t->notify_on_close != nullptr) { |
|
|
|
if (t->notify_on_close != nullptr) { |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, t->notify_on_close, |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, t->notify_on_close, error); |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
|
|
|
|
t->notify_on_close = nullptr; |
|
|
|
t->notify_on_close = nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG |
|
|
|
#ifndef NDEBUG |
|
|
@ -699,8 +693,6 @@ grpc_chttp2_stream::~grpc_chttp2_stream() { |
|
|
|
GPR_ASSERT(recv_message_ready == nullptr); |
|
|
|
GPR_ASSERT(recv_message_ready == nullptr); |
|
|
|
GPR_ASSERT(recv_trailing_metadata_finished == nullptr); |
|
|
|
GPR_ASSERT(recv_trailing_metadata_finished == nullptr); |
|
|
|
grpc_slice_buffer_destroy(&flow_controlled_buffer); |
|
|
|
grpc_slice_buffer_destroy(&flow_controlled_buffer); |
|
|
|
GRPC_ERROR_UNREF(read_closed_error); |
|
|
|
|
|
|
|
GRPC_ERROR_UNREF(write_closed_error); |
|
|
|
|
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "stream"); |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "stream"); |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, destroy_stream_arg, GRPC_ERROR_NONE); |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, destroy_stream_arg, GRPC_ERROR_NONE); |
|
|
|
} |
|
|
|
} |
|
|
@ -774,7 +766,7 @@ static void set_write_state(grpc_chttp2_transport* t, |
|
|
|
// from peer while we had some pending writes)
|
|
|
|
// from peer while we had some pending writes)
|
|
|
|
if (st == GRPC_CHTTP2_WRITE_STATE_IDLE) { |
|
|
|
if (st == GRPC_CHTTP2_WRITE_STATE_IDLE) { |
|
|
|
grpc_core::ExecCtx::RunList(DEBUG_LOCATION, &t->run_after_write); |
|
|
|
grpc_core::ExecCtx::RunList(DEBUG_LOCATION, &t->run_after_write); |
|
|
|
if (!GRPC_ERROR_IS_NONE(t->close_transport_on_writes_finished)) { |
|
|
|
if (!t->close_transport_on_writes_finished.ok()) { |
|
|
|
grpc_error_handle err = t->close_transport_on_writes_finished; |
|
|
|
grpc_error_handle err = t->close_transport_on_writes_finished; |
|
|
|
t->close_transport_on_writes_finished = GRPC_ERROR_NONE; |
|
|
|
t->close_transport_on_writes_finished = GRPC_ERROR_NONE; |
|
|
|
close_transport_locked(t, err); |
|
|
|
close_transport_locked(t, err); |
|
|
@ -821,8 +813,7 @@ void grpc_chttp2_initiate_write(grpc_chttp2_transport* t, |
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_mark_stream_writable(grpc_chttp2_transport* t, |
|
|
|
void grpc_chttp2_mark_stream_writable(grpc_chttp2_transport* t, |
|
|
|
grpc_chttp2_stream* s) { |
|
|
|
grpc_chttp2_stream* s) { |
|
|
|
if (GRPC_ERROR_IS_NONE(t->closed_with_error) && |
|
|
|
if (t->closed_with_error.ok() && grpc_chttp2_list_add_writable_stream(t, s)) { |
|
|
|
grpc_chttp2_list_add_writable_stream(t, s)) { |
|
|
|
|
|
|
|
GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:become"); |
|
|
|
GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:become"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -840,7 +831,7 @@ static void write_action_begin_locked(void* gt, |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(gt); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(gt); |
|
|
|
GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); |
|
|
|
GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); |
|
|
|
grpc_chttp2_begin_write_result r; |
|
|
|
grpc_chttp2_begin_write_result r; |
|
|
|
if (!GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
if (!t->closed_with_error.ok()) { |
|
|
|
r.writing = false; |
|
|
|
r.writing = false; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
r = grpc_chttp2_begin_write(t); |
|
|
|
r = grpc_chttp2_begin_write(t); |
|
|
@ -895,7 +886,7 @@ static void write_action_end(void* tp, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->write_action_end_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->write_action_end_locked, |
|
|
|
write_action_end_locked, t, nullptr), |
|
|
|
write_action_end_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Callback from the grpc_endpoint after bytes have been written by calling
|
|
|
|
// Callback from the grpc_endpoint after bytes have been written by calling
|
|
|
@ -904,8 +895,8 @@ static void write_action_end_locked(void* tp, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
|
|
|
|
|
|
|
|
bool closed = false; |
|
|
|
bool closed = false; |
|
|
|
if (!GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (!error.ok()) { |
|
|
|
close_transport_locked(t, GRPC_ERROR_REF(error)); |
|
|
|
close_transport_locked(t, error); |
|
|
|
closed = true; |
|
|
|
closed = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -942,7 +933,7 @@ static void write_action_end_locked(void* tp, grpc_error_handle error) { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
grpc_chttp2_end_write(t, GRPC_ERROR_REF(error)); |
|
|
|
grpc_chttp2_end_write(t, error); |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "writing"); |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "writing"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -971,9 +962,8 @@ static void cancel_unstarted_streams(grpc_chttp2_transport* t, |
|
|
|
s->trailing_metadata_buffer.Set( |
|
|
|
s->trailing_metadata_buffer.Set( |
|
|
|
grpc_core::GrpcStreamNetworkState(), |
|
|
|
grpc_core::GrpcStreamNetworkState(), |
|
|
|
grpc_core::GrpcStreamNetworkState::kNotSentOnWire); |
|
|
|
grpc_core::GrpcStreamNetworkState::kNotSentOnWire); |
|
|
|
grpc_chttp2_cancel_stream(t, s, GRPC_ERROR_REF(error)); |
|
|
|
grpc_chttp2_cancel_stream(t, s, error); |
|
|
|
} |
|
|
|
} |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, |
|
|
|
void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, |
|
|
@ -981,8 +971,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, |
|
|
|
uint32_t last_stream_id, |
|
|
|
uint32_t last_stream_id, |
|
|
|
absl::string_view goaway_text) { |
|
|
|
absl::string_view goaway_text) { |
|
|
|
// Discard the error from a previous goaway frame (if any)
|
|
|
|
// Discard the error from a previous goaway frame (if any)
|
|
|
|
if (!GRPC_ERROR_IS_NONE(t->goaway_error)) { |
|
|
|
if (!t->goaway_error.ok()) { |
|
|
|
GRPC_ERROR_UNREF(t->goaway_error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
t->goaway_error = grpc_error_set_str( |
|
|
|
t->goaway_error = grpc_error_set_str( |
|
|
|
grpc_error_set_int( |
|
|
|
grpc_error_set_int( |
|
|
@ -1002,7 +991,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, |
|
|
|
goaway_error, grpc_error_std_string(t->goaway_error).c_str()); |
|
|
|
goaway_error, grpc_error_std_string(t->goaway_error).c_str()); |
|
|
|
} |
|
|
|
} |
|
|
|
if (t->is_client) { |
|
|
|
if (t->is_client) { |
|
|
|
cancel_unstarted_streams(t, GRPC_ERROR_REF(t->goaway_error)); |
|
|
|
cancel_unstarted_streams(t, t->goaway_error); |
|
|
|
// Cancel all unseen streams
|
|
|
|
// Cancel all unseen streams
|
|
|
|
grpc_chttp2_stream_map_for_each( |
|
|
|
grpc_chttp2_stream_map_for_each( |
|
|
|
&t->stream_map, |
|
|
|
&t->stream_map, |
|
|
@ -1013,8 +1002,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, |
|
|
|
s->trailing_metadata_buffer.Set( |
|
|
|
s->trailing_metadata_buffer.Set( |
|
|
|
grpc_core::GrpcStreamNetworkState(), |
|
|
|
grpc_core::GrpcStreamNetworkState(), |
|
|
|
grpc_core::GrpcStreamNetworkState::kNotSeenByServer); |
|
|
|
grpc_core::GrpcStreamNetworkState::kNotSeenByServer); |
|
|
|
grpc_chttp2_cancel_stream(s->t, s, |
|
|
|
grpc_chttp2_cancel_stream(s->t, s, s->t->goaway_error); |
|
|
|
GRPC_ERROR_REF(s->t->goaway_error)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
&last_stream_id); |
|
|
|
&last_stream_id); |
|
|
@ -1053,8 +1041,8 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t) { |
|
|
|
grpc_chttp2_stream* s; |
|
|
|
grpc_chttp2_stream* s; |
|
|
|
// maybe cancel out streams that haven't yet started if we have received a
|
|
|
|
// maybe cancel out streams that haven't yet started if we have received a
|
|
|
|
// GOAWAY
|
|
|
|
// GOAWAY
|
|
|
|
if (!GRPC_ERROR_IS_NONE(t->goaway_error)) { |
|
|
|
if (!t->goaway_error.ok()) { |
|
|
|
cancel_unstarted_streams(t, GRPC_ERROR_REF(t->goaway_error)); |
|
|
|
cancel_unstarted_streams(t, t->goaway_error); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
// start streams where we have free grpc_chttp2_stream ids and free
|
|
|
|
// start streams where we have free grpc_chttp2_stream ids and free
|
|
|
@ -1134,7 +1122,6 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, |
|
|
|
grpc_closure* closure = *pclosure; |
|
|
|
grpc_closure* closure = *pclosure; |
|
|
|
*pclosure = nullptr; |
|
|
|
*pclosure = nullptr; |
|
|
|
if (closure == nullptr) { |
|
|
|
if (closure == nullptr) { |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT; |
|
|
|
closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT; |
|
|
@ -1151,10 +1138,10 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, |
|
|
|
desc, grpc_error_std_string(error).c_str(), |
|
|
|
desc, grpc_error_std_string(error).c_str(), |
|
|
|
write_state_name(t->write_state)); |
|
|
|
write_state_name(t->write_state)); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (!error.ok()) { |
|
|
|
grpc_error_handle cl_err = |
|
|
|
grpc_error_handle cl_err = |
|
|
|
grpc_core::internal::StatusMoveFromHeapPtr(closure->error_data.error); |
|
|
|
grpc_core::internal::StatusMoveFromHeapPtr(closure->error_data.error); |
|
|
|
if (GRPC_ERROR_IS_NONE(cl_err)) { |
|
|
|
if (cl_err.ok()) { |
|
|
|
cl_err = GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat( |
|
|
|
cl_err = GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat( |
|
|
|
"Error in HTTP transport completing operation: ", desc, |
|
|
|
"Error in HTTP transport completing operation: ", desc, |
|
|
|
" write_state=", write_state_name(t->write_state), " refs=", |
|
|
|
" write_state=", write_state_name(t->write_state), " refs=", |
|
|
@ -1255,7 +1242,7 @@ static void perform_stream_op_locked(void* stream_op, |
|
|
|
} |
|
|
|
} |
|
|
|
if (!s->write_closed) { |
|
|
|
if (!s->write_closed) { |
|
|
|
if (t->is_client) { |
|
|
|
if (t->is_client) { |
|
|
|
if (GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
if (t->closed_with_error.ok()) { |
|
|
|
GPR_ASSERT(s->id == 0); |
|
|
|
GPR_ASSERT(s->id == 0); |
|
|
|
grpc_chttp2_list_add_waiting_for_concurrency(t, s); |
|
|
|
grpc_chttp2_list_add_waiting_for_concurrency(t, s); |
|
|
|
maybe_start_some_streams(t); |
|
|
|
maybe_start_some_streams(t); |
|
|
@ -1481,21 +1468,18 @@ static void cancel_pings(grpc_chttp2_transport* t, grpc_error_handle error) { |
|
|
|
// callback remaining pings: they're not allowed to call into the transport,
|
|
|
|
// callback remaining pings: they're not allowed to call into the transport,
|
|
|
|
// and maybe they hold resources that need to be freed
|
|
|
|
// and maybe they hold resources that need to be freed
|
|
|
|
grpc_chttp2_ping_queue* pq = &t->ping_queue; |
|
|
|
grpc_chttp2_ping_queue* pq = &t->ping_queue; |
|
|
|
GPR_ASSERT(!GRPC_ERROR_IS_NONE(error)); |
|
|
|
GPR_ASSERT(!error.ok()); |
|
|
|
for (size_t j = 0; j < GRPC_CHTTP2_PCL_COUNT; j++) { |
|
|
|
for (size_t j = 0; j < GRPC_CHTTP2_PCL_COUNT; j++) { |
|
|
|
grpc_closure_list_fail_all(&pq->lists[j], GRPC_ERROR_REF(error)); |
|
|
|
grpc_closure_list_fail_all(&pq->lists[j], error); |
|
|
|
grpc_core::ExecCtx::RunList(DEBUG_LOCATION, &pq->lists[j]); |
|
|
|
grpc_core::ExecCtx::RunList(DEBUG_LOCATION, &pq->lists[j]); |
|
|
|
} |
|
|
|
} |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void send_ping_locked(grpc_chttp2_transport* t, |
|
|
|
static void send_ping_locked(grpc_chttp2_transport* t, |
|
|
|
grpc_closure* on_initiate, grpc_closure* on_ack) { |
|
|
|
grpc_closure* on_initiate, grpc_closure* on_ack) { |
|
|
|
if (!GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
if (!t->closed_with_error.ok()) { |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_initiate, |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_initiate, t->closed_with_error); |
|
|
|
GRPC_ERROR_REF(t->closed_with_error)); |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_ack, t->closed_with_error); |
|
|
|
grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_ack, |
|
|
|
|
|
|
|
GRPC_ERROR_REF(t->closed_with_error)); |
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
grpc_chttp2_ping_queue* pq = &t->ping_queue; |
|
|
|
grpc_chttp2_ping_queue* pq = &t->ping_queue; |
|
|
@ -1509,14 +1493,14 @@ static void send_ping_locked(grpc_chttp2_transport* t, |
|
|
|
// a ping in progress, the keepalive ping would piggyback onto that ping,
|
|
|
|
// a ping in progress, the keepalive ping would piggyback onto that ping,
|
|
|
|
// instead of waiting for that ping to complete and then starting a new ping.
|
|
|
|
// instead of waiting for that ping to complete and then starting a new ping.
|
|
|
|
static void send_keepalive_ping_locked(grpc_chttp2_transport* t) { |
|
|
|
static void send_keepalive_ping_locked(grpc_chttp2_transport* t) { |
|
|
|
if (!GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
if (!t->closed_with_error.ok()) { |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->start_keepalive_ping_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->start_keepalive_ping_locked, |
|
|
|
start_keepalive_ping_locked, t, nullptr), |
|
|
|
start_keepalive_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(t->closed_with_error)); |
|
|
|
t->closed_with_error); |
|
|
|
t->combiner->Run( |
|
|
|
t->combiner->Run( |
|
|
|
GRPC_CLOSURE_INIT(&t->finish_keepalive_ping_locked, |
|
|
|
GRPC_CLOSURE_INIT(&t->finish_keepalive_ping_locked, |
|
|
|
finish_keepalive_ping_locked, t, nullptr), |
|
|
|
finish_keepalive_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(t->closed_with_error)); |
|
|
|
t->closed_with_error); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
grpc_chttp2_ping_queue* pq = &t->ping_queue; |
|
|
|
grpc_chttp2_ping_queue* pq = &t->ping_queue; |
|
|
@ -1524,7 +1508,7 @@ static void send_keepalive_ping_locked(grpc_chttp2_transport* t) { |
|
|
|
// There is a ping in flight. Add yourself to the inflight closure list.
|
|
|
|
// There is a ping in flight. Add yourself to the inflight closure list.
|
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->start_keepalive_ping_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->start_keepalive_ping_locked, |
|
|
|
start_keepalive_ping_locked, t, nullptr), |
|
|
|
start_keepalive_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(t->closed_with_error)); |
|
|
|
t->closed_with_error); |
|
|
|
grpc_closure_list_append( |
|
|
|
grpc_closure_list_append( |
|
|
|
&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT], |
|
|
|
&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT], |
|
|
|
GRPC_CLOSURE_INIT(&t->finish_keepalive_ping_locked, |
|
|
|
GRPC_CLOSURE_INIT(&t->finish_keepalive_ping_locked, |
|
|
@ -1548,13 +1532,13 @@ void grpc_chttp2_retry_initiate_ping(void* tp, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->retry_initiate_ping_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->retry_initiate_ping_locked, |
|
|
|
retry_initiate_ping_locked, t, nullptr), |
|
|
|
retry_initiate_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void retry_initiate_ping_locked(void* tp, grpc_error_handle error) { |
|
|
|
static void retry_initiate_ping_locked(void* tp, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
t->ping_state.is_delayed_ping_timer_set = false; |
|
|
|
t->ping_state.is_delayed_ping_timer_set = false; |
|
|
|
if (GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (error.ok()) { |
|
|
|
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RETRY_SEND_PING); |
|
|
|
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RETRY_SEND_PING); |
|
|
|
} |
|
|
|
} |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "retry_initiate_ping_locked"); |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "retry_initiate_ping_locked"); |
|
|
@ -1610,7 +1594,7 @@ class GracefulGoaway : public grpc_core::RefCounted<GracefulGoaway> { |
|
|
|
// We already sent the final GOAWAY.
|
|
|
|
// We already sent the final GOAWAY.
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (t_->destroying || !GRPC_ERROR_IS_NONE(t_->closed_with_error)) { |
|
|
|
if (t_->destroying || !t_->closed_with_error.ok()) { |
|
|
|
GRPC_CHTTP2_IF_TRACING(gpr_log( |
|
|
|
GRPC_CHTTP2_IF_TRACING(gpr_log( |
|
|
|
GPR_INFO, |
|
|
|
GPR_INFO, |
|
|
|
"transport:%p %s peer:%s Transport already shutting down. " |
|
|
|
"transport:%p %s peer:%s Transport already shutting down. " |
|
|
@ -1647,7 +1631,7 @@ class GracefulGoaway : public grpc_core::RefCounted<GracefulGoaway> { |
|
|
|
|
|
|
|
|
|
|
|
static void OnTimer(void* arg, grpc_error_handle error) { |
|
|
|
static void OnTimer(void* arg, grpc_error_handle error) { |
|
|
|
auto* self = static_cast<GracefulGoaway*>(arg); |
|
|
|
auto* self = static_cast<GracefulGoaway*>(arg); |
|
|
|
if (!GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (!error.ok()) { |
|
|
|
self->Unref(); |
|
|
|
self->Unref(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -1697,7 +1681,6 @@ static void send_goaway(grpc_chttp2_transport* t, grpc_error_handle error, |
|
|
|
// Final GOAWAY has already been sent.
|
|
|
|
// Final GOAWAY has already been sent.
|
|
|
|
} |
|
|
|
} |
|
|
|
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_GOAWAY_SENT); |
|
|
|
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_GOAWAY_SENT); |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_add_ping_strike(grpc_chttp2_transport* t) { |
|
|
|
void grpc_chttp2_add_ping_strike(grpc_chttp2_transport* t) { |
|
|
@ -1731,7 +1714,7 @@ static void perform_transport_op_locked(void* stream_op, |
|
|
|
grpc_chttp2_transport* t = |
|
|
|
grpc_chttp2_transport* t = |
|
|
|
static_cast<grpc_chttp2_transport*>(op->handler_private.extra_arg); |
|
|
|
static_cast<grpc_chttp2_transport*>(op->handler_private.extra_arg); |
|
|
|
|
|
|
|
|
|
|
|
if (!GRPC_ERROR_IS_NONE(op->goaway_error)) { |
|
|
|
if (!op->goaway_error.ok()) { |
|
|
|
send_goaway(t, op->goaway_error, /*immediate_disconnect_hint=*/false); |
|
|
|
send_goaway(t, op->goaway_error, /*immediate_disconnect_hint=*/false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1761,8 +1744,8 @@ static void perform_transport_op_locked(void* stream_op, |
|
|
|
t->state_tracker.RemoveWatcher(op->stop_connectivity_watch); |
|
|
|
t->state_tracker.RemoveWatcher(op->stop_connectivity_watch); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!GRPC_ERROR_IS_NONE(op->disconnect_with_error)) { |
|
|
|
if (!op->disconnect_with_error.ok()) { |
|
|
|
send_goaway(t, GRPC_ERROR_REF(op->disconnect_with_error), |
|
|
|
send_goaway(t, op->disconnect_with_error, |
|
|
|
/*immediate_disconnect_hint=*/true); |
|
|
|
/*immediate_disconnect_hint=*/true); |
|
|
|
close_transport_locked(t, op->disconnect_with_error); |
|
|
|
close_transport_locked(t, op->disconnect_with_error); |
|
|
|
} |
|
|
|
} |
|
|
@ -1843,7 +1826,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
error = absl::get<grpc_error_handle>(r); |
|
|
|
error = absl::get<grpc_error_handle>(r); |
|
|
|
if (!GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (!error.ok()) { |
|
|
|
s->seen_error = true; |
|
|
|
s->seen_error = true; |
|
|
|
grpc_slice_buffer_reset_and_unref(&s->frame_storage); |
|
|
|
grpc_slice_buffer_reset_and_unref(&s->frame_storage); |
|
|
|
break; |
|
|
|
break; |
|
|
@ -1864,7 +1847,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, |
|
|
|
} |
|
|
|
} |
|
|
|
// save the length of the buffer before handing control back to application
|
|
|
|
// save the length of the buffer before handing control back to application
|
|
|
|
// threads. Needed to support correct flow control bookkeeping
|
|
|
|
// threads. Needed to support correct flow control bookkeeping
|
|
|
|
if (GRPC_ERROR_IS_NONE(error) && s->recv_message->has_value()) { |
|
|
|
if (error.ok() && s->recv_message->has_value()) { |
|
|
|
null_then_sched_closure(&s->recv_message_ready); |
|
|
|
null_then_sched_closure(&s->recv_message_ready); |
|
|
|
} else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { |
|
|
|
} else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { |
|
|
|
if (s->call_failed_before_recv_message != nullptr) { |
|
|
|
if (s->call_failed_before_recv_message != nullptr) { |
|
|
@ -1873,7 +1856,6 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, |
|
|
|
} |
|
|
|
} |
|
|
|
null_then_sched_closure(&s->recv_message_ready); |
|
|
|
null_then_sched_closure(&s->recv_message_ready); |
|
|
|
} |
|
|
|
} |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
}(); |
|
|
|
}(); |
|
|
|
|
|
|
|
|
|
|
|
upd.SetPendingSize(s->frame_storage.length); |
|
|
|
upd.SetPendingSize(s->frame_storage.length); |
|
|
@ -1923,8 +1905,6 @@ static void remove_stream(grpc_chttp2_transport* t, uint32_t id, |
|
|
|
grpc_chttp2_list_remove_stalled_by_stream(t, s); |
|
|
|
grpc_chttp2_list_remove_stalled_by_stream(t, s); |
|
|
|
grpc_chttp2_list_remove_stalled_by_transport(t, s); |
|
|
|
grpc_chttp2_list_remove_stalled_by_transport(t, s); |
|
|
|
|
|
|
|
|
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
maybe_start_some_streams(t); |
|
|
|
maybe_start_some_streams(t); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1946,7 +1926,7 @@ void grpc_chttp2_cancel_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s, |
|
|
|
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM); |
|
|
|
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (!GRPC_ERROR_IS_NONE(due_to_error) && !s->seen_error) { |
|
|
|
if (!due_to_error.ok() && !s->seen_error) { |
|
|
|
s->seen_error = true; |
|
|
|
s->seen_error = true; |
|
|
|
} |
|
|
|
} |
|
|
|
grpc_chttp2_mark_stream_closed(t, s, 1, 1, due_to_error); |
|
|
|
grpc_chttp2_mark_stream_closed(t, s, 1, 1, due_to_error); |
|
|
@ -1978,13 +1958,11 @@ void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* s, |
|
|
|
s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE; |
|
|
|
s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE; |
|
|
|
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); |
|
|
|
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void add_error(grpc_error_handle error, grpc_error_handle* refs, |
|
|
|
static void add_error(grpc_error_handle error, grpc_error_handle* refs, |
|
|
|
size_t* nrefs) { |
|
|
|
size_t* nrefs) { |
|
|
|
if (GRPC_ERROR_IS_NONE(error)) return; |
|
|
|
if (error.ok()) return; |
|
|
|
for (size_t i = 0; i < *nrefs; i++) { |
|
|
|
for (size_t i = 0; i < *nrefs; i++) { |
|
|
|
if (error == refs[i]) { |
|
|
|
if (error == refs[i]) { |
|
|
|
return; |
|
|
|
return; |
|
|
@ -2007,7 +1985,6 @@ static grpc_error_handle removal_error(grpc_error_handle extra_error, |
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(main_error_msg, |
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(main_error_msg, |
|
|
|
refs, nrefs); |
|
|
|
refs, nrefs); |
|
|
|
} |
|
|
|
} |
|
|
|
GRPC_ERROR_UNREF(extra_error); |
|
|
|
|
|
|
|
return error; |
|
|
|
return error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2017,12 +1994,11 @@ static void flush_write_list(grpc_chttp2_transport* t, grpc_chttp2_stream* s, |
|
|
|
while (*list) { |
|
|
|
while (*list) { |
|
|
|
grpc_chttp2_write_cb* cb = *list; |
|
|
|
grpc_chttp2_write_cb* cb = *list; |
|
|
|
*list = cb->next; |
|
|
|
*list = cb->next; |
|
|
|
grpc_chttp2_complete_closure_step(t, s, &cb->closure, GRPC_ERROR_REF(error), |
|
|
|
grpc_chttp2_complete_closure_step(t, s, &cb->closure, error, |
|
|
|
"on_write_finished_cb"); |
|
|
|
"on_write_finished_cb"); |
|
|
|
cb->next = t->write_cb_pool; |
|
|
|
cb->next = t->write_cb_pool; |
|
|
|
t->write_cb_pool = cb; |
|
|
|
t->write_cb_pool = cb; |
|
|
|
} |
|
|
|
} |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void grpc_chttp2_fail_pending_writes(grpc_chttp2_transport* t, |
|
|
|
void grpc_chttp2_fail_pending_writes(grpc_chttp2_transport* t, |
|
|
@ -2032,19 +2008,16 @@ void grpc_chttp2_fail_pending_writes(grpc_chttp2_transport* t, |
|
|
|
removal_error(error, s, "Pending writes failed due to stream closure"); |
|
|
|
removal_error(error, s, "Pending writes failed due to stream closure"); |
|
|
|
s->send_initial_metadata = nullptr; |
|
|
|
s->send_initial_metadata = nullptr; |
|
|
|
grpc_chttp2_complete_closure_step(t, s, &s->send_initial_metadata_finished, |
|
|
|
grpc_chttp2_complete_closure_step(t, s, &s->send_initial_metadata_finished, |
|
|
|
GRPC_ERROR_REF(error), |
|
|
|
error, "send_initial_metadata_finished"); |
|
|
|
"send_initial_metadata_finished"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s->send_trailing_metadata = nullptr; |
|
|
|
s->send_trailing_metadata = nullptr; |
|
|
|
s->sent_trailing_metadata_op = nullptr; |
|
|
|
s->sent_trailing_metadata_op = nullptr; |
|
|
|
grpc_chttp2_complete_closure_step(t, s, &s->send_trailing_metadata_finished, |
|
|
|
grpc_chttp2_complete_closure_step(t, s, &s->send_trailing_metadata_finished, |
|
|
|
GRPC_ERROR_REF(error), |
|
|
|
error, "send_trailing_metadata_finished"); |
|
|
|
"send_trailing_metadata_finished"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grpc_chttp2_complete_closure_step(t, s, &s->send_message_finished, |
|
|
|
grpc_chttp2_complete_closure_step(t, s, &s->send_message_finished, error, |
|
|
|
GRPC_ERROR_REF(error), |
|
|
|
|
|
|
|
"fetching_send_message_finished"); |
|
|
|
"fetching_send_message_finished"); |
|
|
|
flush_write_list(t, s, &s->on_write_finished_cbs, GRPC_ERROR_REF(error)); |
|
|
|
flush_write_list(t, s, &s->on_write_finished_cbs, error); |
|
|
|
flush_write_list(t, s, &s->on_flow_controlled_cbs, error); |
|
|
|
flush_write_list(t, s, &s->on_flow_controlled_cbs, error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2054,7 +2027,7 @@ void grpc_chttp2_mark_stream_closed(grpc_chttp2_transport* t, |
|
|
|
if (s->read_closed && s->write_closed) { |
|
|
|
if (s->read_closed && s->write_closed) { |
|
|
|
// already closed, but we should still fake the status if needed.
|
|
|
|
// already closed, but we should still fake the status if needed.
|
|
|
|
grpc_error_handle overall_error = removal_error(error, s, "Stream removed"); |
|
|
|
grpc_error_handle overall_error = removal_error(error, s, "Stream removed"); |
|
|
|
if (!GRPC_ERROR_IS_NONE(overall_error)) { |
|
|
|
if (!overall_error.ok()) { |
|
|
|
grpc_chttp2_fake_status(t, s, overall_error); |
|
|
|
grpc_chttp2_fake_status(t, s, overall_error); |
|
|
|
} |
|
|
|
} |
|
|
|
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); |
|
|
|
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); |
|
|
@ -2063,26 +2036,25 @@ void grpc_chttp2_mark_stream_closed(grpc_chttp2_transport* t, |
|
|
|
bool closed_read = false; |
|
|
|
bool closed_read = false; |
|
|
|
bool became_closed = false; |
|
|
|
bool became_closed = false; |
|
|
|
if (close_reads && !s->read_closed) { |
|
|
|
if (close_reads && !s->read_closed) { |
|
|
|
s->read_closed_error = GRPC_ERROR_REF(error); |
|
|
|
s->read_closed_error = error; |
|
|
|
s->read_closed = true; |
|
|
|
s->read_closed = true; |
|
|
|
closed_read = true; |
|
|
|
closed_read = true; |
|
|
|
} |
|
|
|
} |
|
|
|
if (close_writes && !s->write_closed) { |
|
|
|
if (close_writes && !s->write_closed) { |
|
|
|
s->write_closed_error = GRPC_ERROR_REF(error); |
|
|
|
s->write_closed_error = error; |
|
|
|
s->write_closed = true; |
|
|
|
s->write_closed = true; |
|
|
|
grpc_chttp2_fail_pending_writes(t, s, GRPC_ERROR_REF(error)); |
|
|
|
grpc_chttp2_fail_pending_writes(t, s, error); |
|
|
|
} |
|
|
|
} |
|
|
|
if (s->read_closed && s->write_closed) { |
|
|
|
if (s->read_closed && s->write_closed) { |
|
|
|
became_closed = true; |
|
|
|
became_closed = true; |
|
|
|
grpc_error_handle overall_error = |
|
|
|
grpc_error_handle overall_error = removal_error(error, s, "Stream removed"); |
|
|
|
removal_error(GRPC_ERROR_REF(error), s, "Stream removed"); |
|
|
|
|
|
|
|
if (s->id != 0) { |
|
|
|
if (s->id != 0) { |
|
|
|
remove_stream(t, s->id, GRPC_ERROR_REF(overall_error)); |
|
|
|
remove_stream(t, s->id, overall_error); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Purge streams waiting on concurrency still waiting for id assignment
|
|
|
|
// Purge streams waiting on concurrency still waiting for id assignment
|
|
|
|
grpc_chttp2_list_remove_waiting_for_concurrency(t, s); |
|
|
|
grpc_chttp2_list_remove_waiting_for_concurrency(t, s); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!GRPC_ERROR_IS_NONE(overall_error)) { |
|
|
|
if (!overall_error.ok()) { |
|
|
|
grpc_chttp2_fake_status(t, s, overall_error); |
|
|
|
grpc_chttp2_fake_status(t, s, overall_error); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -2099,7 +2071,6 @@ void grpc_chttp2_mark_stream_closed(grpc_chttp2_transport* t, |
|
|
|
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); |
|
|
|
grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); |
|
|
|
GRPC_CHTTP2_STREAM_UNREF(s, "chttp2"); |
|
|
|
GRPC_CHTTP2_STREAM_UNREF(s, "chttp2"); |
|
|
|
} |
|
|
|
} |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void close_from_api(grpc_chttp2_transport* t, grpc_chttp2_stream* s, |
|
|
|
static void close_from_api(grpc_chttp2_transport* t, grpc_chttp2_stream* s, |
|
|
@ -2269,7 +2240,7 @@ struct cancel_stream_cb_args { |
|
|
|
static void cancel_stream_cb(void* user_data, uint32_t /*key*/, void* stream) { |
|
|
|
static void cancel_stream_cb(void* user_data, uint32_t /*key*/, void* stream) { |
|
|
|
cancel_stream_cb_args* args = static_cast<cancel_stream_cb_args*>(user_data); |
|
|
|
cancel_stream_cb_args* args = static_cast<cancel_stream_cb_args*>(user_data); |
|
|
|
grpc_chttp2_stream* s = static_cast<grpc_chttp2_stream*>(stream); |
|
|
|
grpc_chttp2_stream* s = static_cast<grpc_chttp2_stream*>(stream); |
|
|
|
grpc_chttp2_cancel_stream(args->t, s, GRPC_ERROR_REF(args->error)); |
|
|
|
grpc_chttp2_cancel_stream(args->t, s, args->error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void end_all_the_calls(grpc_chttp2_transport* t, |
|
|
|
static void end_all_the_calls(grpc_chttp2_transport* t, |
|
|
@ -2281,10 +2252,9 @@ static void end_all_the_calls(grpc_chttp2_transport* t, |
|
|
|
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, |
|
|
|
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, |
|
|
|
GRPC_STATUS_UNAVAILABLE); |
|
|
|
GRPC_STATUS_UNAVAILABLE); |
|
|
|
} |
|
|
|
} |
|
|
|
cancel_unstarted_streams(t, GRPC_ERROR_REF(error)); |
|
|
|
cancel_unstarted_streams(t, error); |
|
|
|
cancel_stream_cb_args args = {error, t}; |
|
|
|
cancel_stream_cb_args args = {error, t}; |
|
|
|
grpc_chttp2_stream_map_for_each(&t->stream_map, cancel_stream_cb, &args); |
|
|
|
grpc_chttp2_stream_map_for_each(&t->stream_map, cancel_stream_cb, &args); |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -2340,11 +2310,11 @@ static grpc_error_handle try_http_parsing(grpc_chttp2_transport* t) { |
|
|
|
grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response); |
|
|
|
grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response); |
|
|
|
|
|
|
|
|
|
|
|
grpc_error_handle parse_error = GRPC_ERROR_NONE; |
|
|
|
grpc_error_handle parse_error = GRPC_ERROR_NONE; |
|
|
|
for (; i < t->read_buffer.count && GRPC_ERROR_IS_NONE(parse_error); i++) { |
|
|
|
for (; i < t->read_buffer.count && parse_error.ok(); i++) { |
|
|
|
parse_error = |
|
|
|
parse_error = |
|
|
|
grpc_http_parser_parse(&parser, t->read_buffer.slices[i], nullptr); |
|
|
|
grpc_http_parser_parse(&parser, t->read_buffer.slices[i], nullptr); |
|
|
|
} |
|
|
|
} |
|
|
|
if (GRPC_ERROR_IS_NONE(parse_error) && |
|
|
|
if (parse_error.ok() && |
|
|
|
(parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) { |
|
|
|
(parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) { |
|
|
|
error = grpc_error_set_int( |
|
|
|
error = grpc_error_set_int( |
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
@ -2353,7 +2323,6 @@ static grpc_error_handle try_http_parsing(grpc_chttp2_transport* t) { |
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, |
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, |
|
|
|
grpc_http2_status_to_grpc_status(response.status)); |
|
|
|
grpc_http2_status_to_grpc_status(response.status)); |
|
|
|
} |
|
|
|
} |
|
|
|
GRPC_ERROR_UNREF(parse_error); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grpc_http_parser_destroy(&parser); |
|
|
|
grpc_http_parser_destroy(&parser); |
|
|
|
grpc_http_response_destroy(&response); |
|
|
|
grpc_http_response_destroy(&response); |
|
|
@ -2364,38 +2333,32 @@ static void read_action(void* tp, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
t->combiner->Run( |
|
|
|
t->combiner->Run( |
|
|
|
GRPC_CLOSURE_INIT(&t->read_action_locked, read_action_locked, t, nullptr), |
|
|
|
GRPC_CLOSURE_INIT(&t->read_action_locked, read_action_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void read_action_locked(void* tp, grpc_error_handle error) { |
|
|
|
static void read_action_locked(void* tp, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
|
|
|
|
|
|
|
|
(void)GRPC_ERROR_REF(error); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grpc_error_handle err = error; |
|
|
|
grpc_error_handle err = error; |
|
|
|
if (!GRPC_ERROR_IS_NONE(err)) { |
|
|
|
if (!err.ok()) { |
|
|
|
err = grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
err = grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
"Endpoint read failed", &err, 1), |
|
|
|
"Endpoint read failed", &err, 1), |
|
|
|
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, |
|
|
|
GRPC_ERROR_INT_OCCURRED_DURING_WRITE, |
|
|
|
t->write_state); |
|
|
|
t->write_state); |
|
|
|
} |
|
|
|
} |
|
|
|
std::swap(err, error); |
|
|
|
std::swap(err, error); |
|
|
|
GRPC_ERROR_UNREF(err); |
|
|
|
if (t->closed_with_error.ok()) { |
|
|
|
if (GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
|
|
|
|
size_t i = 0; |
|
|
|
size_t i = 0; |
|
|
|
grpc_error_handle errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE, |
|
|
|
grpc_error_handle errors[3] = {error, GRPC_ERROR_NONE, GRPC_ERROR_NONE}; |
|
|
|
GRPC_ERROR_NONE}; |
|
|
|
|
|
|
|
for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) { |
|
|
|
for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) { |
|
|
|
errors[1] = grpc_chttp2_perform_read(t, t->read_buffer.slices[i]); |
|
|
|
errors[1] = grpc_chttp2_perform_read(t, t->read_buffer.slices[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
if (errors[1] != GRPC_ERROR_NONE) { |
|
|
|
if (errors[1] != GRPC_ERROR_NONE) { |
|
|
|
errors[2] = try_http_parsing(t); |
|
|
|
errors[2] = try_http_parsing(t); |
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
"Failed parsing HTTP/2", errors, GPR_ARRAY_SIZE(errors)); |
|
|
|
"Failed parsing HTTP/2", errors, GPR_ARRAY_SIZE(errors)); |
|
|
|
} |
|
|
|
} |
|
|
|
for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) { |
|
|
|
for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) { |
|
|
|
GRPC_ERROR_UNREF(errors[i]); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (t->initial_window_update != 0) { |
|
|
|
if (t->initial_window_update != 0) { |
|
|
@ -2412,20 +2375,20 @@ static void read_action_locked(void* tp, grpc_error_handle error) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool keep_reading = false; |
|
|
|
bool keep_reading = false; |
|
|
|
if (GRPC_ERROR_IS_NONE(error) && !GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
if (error.ok() && !t->closed_with_error.ok()) { |
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
"Transport closed", &t->closed_with_error, 1); |
|
|
|
"Transport closed", &t->closed_with_error, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (!error.ok()) { |
|
|
|
// If a goaway frame was received, this might be the reason why the read
|
|
|
|
// If a goaway frame was received, this might be the reason why the read
|
|
|
|
// failed. Add this info to the error
|
|
|
|
// failed. Add this info to the error
|
|
|
|
if (!GRPC_ERROR_IS_NONE(t->goaway_error)) { |
|
|
|
if (!t->goaway_error.ok()) { |
|
|
|
error = grpc_error_add_child(error, GRPC_ERROR_REF(t->goaway_error)); |
|
|
|
error = grpc_error_add_child(error, t->goaway_error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
close_transport_locked(t, GRPC_ERROR_REF(error)); |
|
|
|
close_transport_locked(t, error); |
|
|
|
t->endpoint_reading = 0; |
|
|
|
t->endpoint_reading = 0; |
|
|
|
} else if (GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
} else if (t->closed_with_error.ok()) { |
|
|
|
keep_reading = true; |
|
|
|
keep_reading = true; |
|
|
|
// Since we have read a byte, reset the keepalive timer
|
|
|
|
// Since we have read a byte, reset the keepalive timer
|
|
|
|
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) { |
|
|
|
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) { |
|
|
@ -2448,12 +2411,10 @@ static void read_action_locked(void* tp, grpc_error_handle error) { |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "reading_action"); |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "reading_action"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void continue_read_action_locked(grpc_chttp2_transport* t) { |
|
|
|
static void continue_read_action_locked(grpc_chttp2_transport* t) { |
|
|
|
const bool urgent = !GRPC_ERROR_IS_NONE(t->goaway_error); |
|
|
|
const bool urgent = !t->goaway_error.ok(); |
|
|
|
GRPC_CLOSURE_INIT(&t->read_action_locked, read_action, t, |
|
|
|
GRPC_CLOSURE_INIT(&t->read_action_locked, read_action, t, |
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
grpc_endpoint_read(t->ep, &t->read_buffer, &t->read_action_locked, urgent, |
|
|
|
grpc_endpoint_read(t->ep, &t->read_buffer, &t->read_action_locked, urgent, |
|
|
@ -2477,7 +2438,7 @@ static void start_bdp_ping(void* tp, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->start_bdp_ping_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->start_bdp_ping_locked, |
|
|
|
start_bdp_ping_locked, t, nullptr), |
|
|
|
start_bdp_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void start_bdp_ping_locked(void* tp, grpc_error_handle error) { |
|
|
|
static void start_bdp_ping_locked(void* tp, grpc_error_handle error) { |
|
|
@ -2486,7 +2447,7 @@ static void start_bdp_ping_locked(void* tp, grpc_error_handle error) { |
|
|
|
gpr_log(GPR_INFO, "%s: Start BDP ping err=%s", t->peer_string.c_str(), |
|
|
|
gpr_log(GPR_INFO, "%s: Start BDP ping err=%s", t->peer_string.c_str(), |
|
|
|
grpc_error_std_string(error).c_str()); |
|
|
|
grpc_error_std_string(error).c_str()); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!GRPC_ERROR_IS_NONE(error) || !GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
if (!error.ok() || !t->closed_with_error.ok()) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
// Reset the keepalive ping timer
|
|
|
|
// Reset the keepalive ping timer
|
|
|
@ -2501,7 +2462,7 @@ static void finish_bdp_ping(void* tp, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->finish_bdp_ping_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->finish_bdp_ping_locked, |
|
|
|
finish_bdp_ping_locked, t, nullptr), |
|
|
|
finish_bdp_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void finish_bdp_ping_locked(void* tp, grpc_error_handle error) { |
|
|
|
static void finish_bdp_ping_locked(void* tp, grpc_error_handle error) { |
|
|
@ -2510,7 +2471,7 @@ static void finish_bdp_ping_locked(void* tp, grpc_error_handle error) { |
|
|
|
gpr_log(GPR_INFO, "%s: Complete BDP ping err=%s", t->peer_string.c_str(), |
|
|
|
gpr_log(GPR_INFO, "%s: Complete BDP ping err=%s", t->peer_string.c_str(), |
|
|
|
grpc_error_std_string(error).c_str()); |
|
|
|
grpc_error_std_string(error).c_str()); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!GRPC_ERROR_IS_NONE(error) || !GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
if (!error.ok() || !t->closed_with_error.ok()) { |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "bdp_ping"); |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "bdp_ping"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -2519,7 +2480,7 @@ static void finish_bdp_ping_locked(void* tp, grpc_error_handle error) { |
|
|
|
// finish_bdp_ping_locked to be run later.
|
|
|
|
// finish_bdp_ping_locked to be run later.
|
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->finish_bdp_ping_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->finish_bdp_ping_locked, |
|
|
|
finish_bdp_ping_locked, t, nullptr), |
|
|
|
finish_bdp_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
t->bdp_ping_started = false; |
|
|
|
t->bdp_ping_started = false; |
|
|
@ -2540,7 +2501,7 @@ static void next_bdp_ping_timer_expired(void* tp, grpc_error_handle error) { |
|
|
|
t->combiner->Run( |
|
|
|
t->combiner->Run( |
|
|
|
GRPC_CLOSURE_INIT(&t->next_bdp_ping_timer_expired_locked, |
|
|
|
GRPC_CLOSURE_INIT(&t->next_bdp_ping_timer_expired_locked, |
|
|
|
next_bdp_ping_timer_expired_locked, t, nullptr), |
|
|
|
next_bdp_ping_timer_expired_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void next_bdp_ping_timer_expired_locked(void* tp, |
|
|
|
static void next_bdp_ping_timer_expired_locked(void* tp, |
|
|
@ -2548,7 +2509,7 @@ static void next_bdp_ping_timer_expired_locked(void* tp, |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp); |
|
|
|
GPR_ASSERT(t->have_next_bdp_ping_timer); |
|
|
|
GPR_ASSERT(t->have_next_bdp_ping_timer); |
|
|
|
t->have_next_bdp_ping_timer = false; |
|
|
|
t->have_next_bdp_ping_timer = false; |
|
|
|
if (!GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (!error.ok()) { |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "bdp_ping"); |
|
|
|
GRPC_CHTTP2_UNREF_TRANSPORT(t, "bdp_ping"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -2624,15 +2585,15 @@ static void init_keepalive_ping(void* arg, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->init_keepalive_ping_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->init_keepalive_ping_locked, |
|
|
|
init_keepalive_ping_locked, t, nullptr), |
|
|
|
init_keepalive_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void init_keepalive_ping_locked(void* arg, grpc_error_handle error) { |
|
|
|
static void init_keepalive_ping_locked(void* arg, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING); |
|
|
|
GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING); |
|
|
|
if (t->destroying || !GRPC_ERROR_IS_NONE(t->closed_with_error)) { |
|
|
|
if (t->destroying || !t->closed_with_error.ok()) { |
|
|
|
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; |
|
|
|
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; |
|
|
|
} else if (GRPC_ERROR_IS_NONE(error)) { |
|
|
|
} else if (error.ok()) { |
|
|
|
if (t->keepalive_permit_without_calls || |
|
|
|
if (t->keepalive_permit_without_calls || |
|
|
|
grpc_chttp2_stream_map_size(&t->stream_map) > 0) { |
|
|
|
grpc_chttp2_stream_map_size(&t->stream_map) > 0) { |
|
|
|
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING; |
|
|
|
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING; |
|
|
@ -2669,12 +2630,12 @@ static void start_keepalive_ping(void* arg, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->start_keepalive_ping_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->start_keepalive_ping_locked, |
|
|
|
start_keepalive_ping_locked, t, nullptr), |
|
|
|
start_keepalive_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void start_keepalive_ping_locked(void* arg, grpc_error_handle error) { |
|
|
|
static void start_keepalive_ping_locked(void* arg, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
if (!GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (!error.ok()) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (t->channelz_socket != nullptr) { |
|
|
|
if (t->channelz_socket != nullptr) { |
|
|
@ -2697,13 +2658,13 @@ static void finish_keepalive_ping(void* arg, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->finish_keepalive_ping_locked, |
|
|
|
t->combiner->Run(GRPC_CLOSURE_INIT(&t->finish_keepalive_ping_locked, |
|
|
|
finish_keepalive_ping_locked, t, nullptr), |
|
|
|
finish_keepalive_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void finish_keepalive_ping_locked(void* arg, grpc_error_handle error) { |
|
|
|
static void finish_keepalive_ping_locked(void* arg, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { |
|
|
|
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { |
|
|
|
if (GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (error.ok()) { |
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) || |
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) || |
|
|
|
GRPC_TRACE_FLAG_ENABLED(grpc_keepalive_trace)) { |
|
|
|
GRPC_TRACE_FLAG_ENABLED(grpc_keepalive_trace)) { |
|
|
|
gpr_log(GPR_INFO, "%s: Finish keepalive ping", t->peer_string.c_str()); |
|
|
|
gpr_log(GPR_INFO, "%s: Finish keepalive ping", t->peer_string.c_str()); |
|
|
@ -2714,7 +2675,7 @@ static void finish_keepalive_ping_locked(void* arg, grpc_error_handle error) { |
|
|
|
t->combiner->Run( |
|
|
|
t->combiner->Run( |
|
|
|
GRPC_CLOSURE_INIT(&t->finish_keepalive_ping_locked, |
|
|
|
GRPC_CLOSURE_INIT(&t->finish_keepalive_ping_locked, |
|
|
|
finish_keepalive_ping_locked, t, nullptr), |
|
|
|
finish_keepalive_ping_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
t->keepalive_ping_started = false; |
|
|
|
t->keepalive_ping_started = false; |
|
|
@ -2736,14 +2697,14 @@ static void keepalive_watchdog_fired(void* arg, grpc_error_handle error) { |
|
|
|
t->combiner->Run( |
|
|
|
t->combiner->Run( |
|
|
|
GRPC_CLOSURE_INIT(&t->keepalive_watchdog_fired_locked, |
|
|
|
GRPC_CLOSURE_INIT(&t->keepalive_watchdog_fired_locked, |
|
|
|
keepalive_watchdog_fired_locked, t, nullptr), |
|
|
|
keepalive_watchdog_fired_locked, t, nullptr), |
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void keepalive_watchdog_fired_locked(void* arg, |
|
|
|
static void keepalive_watchdog_fired_locked(void* arg, |
|
|
|
grpc_error_handle error) { |
|
|
|
grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { |
|
|
|
if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { |
|
|
|
if (GRPC_ERROR_IS_NONE(error)) { |
|
|
|
if (error.ok()) { |
|
|
|
gpr_log(GPR_INFO, "%s: Keepalive watchdog fired. Closing transport.", |
|
|
|
gpr_log(GPR_INFO, "%s: Keepalive watchdog fired. Closing transport.", |
|
|
|
t->peer_string.c_str()); |
|
|
|
t->peer_string.c_str()); |
|
|
|
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; |
|
|
|
t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; |
|
|
@ -2839,8 +2800,7 @@ static void post_destructive_reclaimer(grpc_chttp2_transport* t) { |
|
|
|
|
|
|
|
|
|
|
|
static void benign_reclaimer_locked(void* arg, grpc_error_handle error) { |
|
|
|
static void benign_reclaimer_locked(void* arg, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
if (GRPC_ERROR_IS_NONE(error) && |
|
|
|
if (error.ok() && grpc_chttp2_stream_map_size(&t->stream_map) == 0) { |
|
|
|
grpc_chttp2_stream_map_size(&t->stream_map) == 0) { |
|
|
|
|
|
|
|
// Channel with no active streams: send a goaway to try and make it
|
|
|
|
// Channel with no active streams: send a goaway to try and make it
|
|
|
|
// disconnect cleanly
|
|
|
|
// disconnect cleanly
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { |
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { |
|
|
@ -2852,8 +2812,7 @@ static void benign_reclaimer_locked(void* arg, grpc_error_handle error) { |
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"), |
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"), |
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM), |
|
|
|
GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM), |
|
|
|
/*immediate_disconnect_hint=*/true); |
|
|
|
/*immediate_disconnect_hint=*/true); |
|
|
|
} else if (GRPC_ERROR_IS_NONE(error) && |
|
|
|
} else if (error.ok() && GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { |
|
|
|
GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { |
|
|
|
|
|
|
|
gpr_log(GPR_INFO, |
|
|
|
gpr_log(GPR_INFO, |
|
|
|
"HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR |
|
|
|
"HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR |
|
|
|
" streams", |
|
|
|
" streams", |
|
|
@ -2871,7 +2830,7 @@ static void destructive_reclaimer_locked(void* arg, grpc_error_handle error) { |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(arg); |
|
|
|
size_t n = grpc_chttp2_stream_map_size(&t->stream_map); |
|
|
|
size_t n = grpc_chttp2_stream_map_size(&t->stream_map); |
|
|
|
t->destructive_reclaimer_registered = false; |
|
|
|
t->destructive_reclaimer_registered = false; |
|
|
|
if (GRPC_ERROR_IS_NONE(error) && n > 0) { |
|
|
|
if (error.ok() && n > 0) { |
|
|
|
grpc_chttp2_stream* s = static_cast<grpc_chttp2_stream*>( |
|
|
|
grpc_chttp2_stream* s = static_cast<grpc_chttp2_stream*>( |
|
|
|
grpc_chttp2_stream_map_rand(&t->stream_map)); |
|
|
|
grpc_chttp2_stream_map_rand(&t->stream_map)); |
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { |
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { |
|
|
|