|
|
|
@ -1412,64 +1412,44 @@ static void perform_stream_op_locked(void* stream_op, |
|
|
|
|
s->send_initial_metadata_finished = add_closure_barrier(on_complete); |
|
|
|
|
s->send_initial_metadata = |
|
|
|
|
op_payload->send_initial_metadata.send_initial_metadata; |
|
|
|
|
const size_t metadata_size = |
|
|
|
|
grpc_metadata_batch_size(s->send_initial_metadata); |
|
|
|
|
const size_t metadata_peer_limit = |
|
|
|
|
t->settings[GRPC_PEER_SETTINGS] |
|
|
|
|
[GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; |
|
|
|
|
if (t->is_client) { |
|
|
|
|
s->deadline = GPR_MIN(s->deadline, s->send_initial_metadata->deadline); |
|
|
|
|
} |
|
|
|
|
if (metadata_size > metadata_peer_limit) { |
|
|
|
|
grpc_chttp2_cancel_stream( |
|
|
|
|
t, s, |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"to-be-sent initial metadata size " |
|
|
|
|
"exceeds peer limit"), |
|
|
|
|
GRPC_ERROR_INT_SIZE, |
|
|
|
|
static_cast<intptr_t>(metadata_size)), |
|
|
|
|
GRPC_ERROR_INT_LIMIT, |
|
|
|
|
static_cast<intptr_t>(metadata_peer_limit)), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); |
|
|
|
|
} else { |
|
|
|
|
if (contains_non_ok_status(s->send_initial_metadata)) { |
|
|
|
|
s->seen_error = true; |
|
|
|
|
} |
|
|
|
|
if (!s->write_closed) { |
|
|
|
|
if (t->is_client) { |
|
|
|
|
if (t->closed_with_error == GRPC_ERROR_NONE) { |
|
|
|
|
GPR_ASSERT(s->id == 0); |
|
|
|
|
grpc_chttp2_list_add_waiting_for_concurrency(t, s); |
|
|
|
|
maybe_start_some_streams(t); |
|
|
|
|
} else { |
|
|
|
|
grpc_chttp2_cancel_stream( |
|
|
|
|
t, s, |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Transport closed", &t->closed_with_error, 1), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); |
|
|
|
|
} |
|
|
|
|
if (contains_non_ok_status(s->send_initial_metadata)) { |
|
|
|
|
s->seen_error = true; |
|
|
|
|
} |
|
|
|
|
if (!s->write_closed) { |
|
|
|
|
if (t->is_client) { |
|
|
|
|
if (t->closed_with_error == GRPC_ERROR_NONE) { |
|
|
|
|
GPR_ASSERT(s->id == 0); |
|
|
|
|
grpc_chttp2_list_add_waiting_for_concurrency(t, s); |
|
|
|
|
maybe_start_some_streams(t); |
|
|
|
|
} else { |
|
|
|
|
GPR_ASSERT(s->id != 0); |
|
|
|
|
grpc_chttp2_mark_stream_writable(t, s); |
|
|
|
|
if (!(op->send_message && |
|
|
|
|
(op->payload->send_message.send_message->flags() & |
|
|
|
|
GRPC_WRITE_BUFFER_HINT))) { |
|
|
|
|
grpc_chttp2_initiate_write( |
|
|
|
|
t, GRPC_CHTTP2_INITIATE_WRITE_SEND_INITIAL_METADATA); |
|
|
|
|
} |
|
|
|
|
grpc_chttp2_cancel_stream( |
|
|
|
|
t, s, |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Transport closed", &t->closed_with_error, 1), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
s->send_initial_metadata = nullptr; |
|
|
|
|
grpc_chttp2_complete_closure_step( |
|
|
|
|
t, s, &s->send_initial_metadata_finished, |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Attempt to send initial metadata after stream was closed", |
|
|
|
|
&s->write_closed_error, 1), |
|
|
|
|
"send_initial_metadata_finished"); |
|
|
|
|
GPR_ASSERT(s->id != 0); |
|
|
|
|
grpc_chttp2_mark_stream_writable(t, s); |
|
|
|
|
if (!(op->send_message && |
|
|
|
|
(op->payload->send_message.send_message->flags() & |
|
|
|
|
GRPC_WRITE_BUFFER_HINT))) { |
|
|
|
|
grpc_chttp2_initiate_write( |
|
|
|
|
t, GRPC_CHTTP2_INITIATE_WRITE_SEND_INITIAL_METADATA); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
s->send_initial_metadata = nullptr; |
|
|
|
|
grpc_chttp2_complete_closure_step( |
|
|
|
|
t, s, &s->send_initial_metadata_finished, |
|
|
|
|
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( |
|
|
|
|
"Attempt to send initial metadata after stream was closed", |
|
|
|
|
&s->write_closed_error, 1), |
|
|
|
|
"send_initial_metadata_finished"); |
|
|
|
|
} |
|
|
|
|
if (op_payload->send_initial_metadata.peer_string != nullptr) { |
|
|
|
|
gpr_atm_rel_store(op_payload->send_initial_metadata.peer_string, |
|
|
|
@ -1531,47 +1511,27 @@ static void perform_stream_op_locked(void* stream_op, |
|
|
|
|
op_payload->send_trailing_metadata.send_trailing_metadata; |
|
|
|
|
s->sent_trailing_metadata_op = op_payload->send_trailing_metadata.sent; |
|
|
|
|
s->write_buffering = false; |
|
|
|
|
const size_t metadata_size = |
|
|
|
|
grpc_metadata_batch_size(s->send_trailing_metadata); |
|
|
|
|
const size_t metadata_peer_limit = |
|
|
|
|
t->settings[GRPC_PEER_SETTINGS] |
|
|
|
|
[GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; |
|
|
|
|
if (metadata_size > metadata_peer_limit) { |
|
|
|
|
grpc_chttp2_cancel_stream( |
|
|
|
|
t, s, |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
grpc_error_set_int( |
|
|
|
|
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"to-be-sent trailing metadata size " |
|
|
|
|
"exceeds peer limit"), |
|
|
|
|
GRPC_ERROR_INT_SIZE, |
|
|
|
|
static_cast<intptr_t>(metadata_size)), |
|
|
|
|
GRPC_ERROR_INT_LIMIT, |
|
|
|
|
static_cast<intptr_t>(metadata_peer_limit)), |
|
|
|
|
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); |
|
|
|
|
} else { |
|
|
|
|
if (contains_non_ok_status(s->send_trailing_metadata)) { |
|
|
|
|
s->seen_error = true; |
|
|
|
|
} |
|
|
|
|
if (s->write_closed) { |
|
|
|
|
s->send_trailing_metadata = nullptr; |
|
|
|
|
s->sent_trailing_metadata_op = nullptr; |
|
|
|
|
grpc_chttp2_complete_closure_step( |
|
|
|
|
t, s, &s->send_trailing_metadata_finished, |
|
|
|
|
grpc_metadata_batch_is_empty( |
|
|
|
|
op->payload->send_trailing_metadata.send_trailing_metadata) |
|
|
|
|
? GRPC_ERROR_NONE |
|
|
|
|
: GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"Attempt to send trailing metadata after " |
|
|
|
|
"stream was closed"), |
|
|
|
|
"send_trailing_metadata_finished"); |
|
|
|
|
} else if (s->id != 0) { |
|
|
|
|
// TODO(ctiller): check if there's flow control for any outstanding
|
|
|
|
|
// bytes before going writable
|
|
|
|
|
grpc_chttp2_mark_stream_writable(t, s); |
|
|
|
|
grpc_chttp2_initiate_write( |
|
|
|
|
t, GRPC_CHTTP2_INITIATE_WRITE_SEND_TRAILING_METADATA); |
|
|
|
|
} |
|
|
|
|
if (contains_non_ok_status(s->send_trailing_metadata)) { |
|
|
|
|
s->seen_error = true; |
|
|
|
|
} |
|
|
|
|
if (s->write_closed) { |
|
|
|
|
s->send_trailing_metadata = nullptr; |
|
|
|
|
s->sent_trailing_metadata_op = nullptr; |
|
|
|
|
grpc_chttp2_complete_closure_step( |
|
|
|
|
t, s, &s->send_trailing_metadata_finished, |
|
|
|
|
grpc_metadata_batch_is_empty( |
|
|
|
|
op->payload->send_trailing_metadata.send_trailing_metadata) |
|
|
|
|
? GRPC_ERROR_NONE |
|
|
|
|
: GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"Attempt to send trailing metadata after " |
|
|
|
|
"stream was closed"), |
|
|
|
|
"send_trailing_metadata_finished"); |
|
|
|
|
} else if (s->id != 0) { |
|
|
|
|
// TODO(ctiller): check if there's flow control for any outstanding
|
|
|
|
|
// bytes before going writable
|
|
|
|
|
grpc_chttp2_mark_stream_writable(t, s); |
|
|
|
|
grpc_chttp2_initiate_write( |
|
|
|
|
t, GRPC_CHTTP2_INITIATE_WRITE_SEND_TRAILING_METADATA); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|