|
|
|
@ -163,11 +163,9 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx, |
|
|
|
|
GPR_ASSERT(t->lists[i].tail == NULL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GPR_ASSERT(grpc_chttp2_stream_map_size(&t->parsing_stream_map) == 0); |
|
|
|
|
GPR_ASSERT(grpc_chttp2_stream_map_size(&t->new_stream_map) == 0); |
|
|
|
|
GPR_ASSERT(grpc_chttp2_stream_map_size(&t->stream_map) == 0); |
|
|
|
|
|
|
|
|
|
grpc_chttp2_stream_map_destroy(&t->parsing_stream_map); |
|
|
|
|
grpc_chttp2_stream_map_destroy(&t->new_stream_map); |
|
|
|
|
grpc_chttp2_stream_map_destroy(&t->stream_map); |
|
|
|
|
grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker); |
|
|
|
|
|
|
|
|
|
grpc_combiner_destroy(exec_ctx, t->executor.combiner); |
|
|
|
@ -277,8 +275,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, |
|
|
|
|
large enough that the exponential growth should happen nicely when it's |
|
|
|
|
needed. |
|
|
|
|
TODO(ctiller): tune this */ |
|
|
|
|
grpc_chttp2_stream_map_init(&t->parsing_stream_map, 8); |
|
|
|
|
grpc_chttp2_stream_map_init(&t->new_stream_map, 8); |
|
|
|
|
grpc_chttp2_stream_map_init(&t->stream_map, 8); |
|
|
|
|
|
|
|
|
|
/* copy in initial settings to all setting sets */ |
|
|
|
|
for (i = 0; i < GRPC_CHTTP2_NUM_SETTINGS; i++) { |
|
|
|
@ -501,7 +498,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, |
|
|
|
|
REF_TRANSPORT(t, "stream"); |
|
|
|
|
|
|
|
|
|
if (server_data) { |
|
|
|
|
GPR_ASSERT(t->executor.parsing_active); |
|
|
|
|
s->global.id = (uint32_t)(uintptr_t)server_data; |
|
|
|
|
s->global.outgoing_window = |
|
|
|
|
t->global.settings[GRPC_PEER_SETTINGS] |
|
|
|
@ -510,15 +506,16 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, |
|
|
|
|
t->global.settings[GRPC_SENT_SETTINGS] |
|
|
|
|
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]; |
|
|
|
|
*t->accepting_stream = s; |
|
|
|
|
grpc_chttp2_stream_map_add(&t->parsing_stream_map, s->global.id, s); |
|
|
|
|
grpc_chttp2_stream_map_add(&t->stream_map, s->global.id, s); |
|
|
|
|
grpc_chttp2_register_stream(t, s); |
|
|
|
|
s->global.in_stream_map = true; |
|
|
|
|
} else { |
|
|
|
|
grpc_closure_init(&s->init_stream, finish_init_stream_locked, s); |
|
|
|
|
GRPC_CHTTP2_STREAM_REF(&s->global, "init"); |
|
|
|
|
grpc_combiner_execute(exec_ctx, t->executor.combiner, &s->init_stream, |
|
|
|
|
GRPC_ERROR_NONE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grpc_closure_init(&s->init_stream, finish_init_stream_locked, s); |
|
|
|
|
GRPC_CHTTP2_STREAM_REF(&s->global, "init"); |
|
|
|
|
grpc_combiner_execute(exec_ctx, t->executor.combiner, &s->init_stream, |
|
|
|
|
GRPC_ERROR_NONE); |
|
|
|
|
|
|
|
|
|
GPR_TIMER_END("init_stream", 0); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
@ -540,9 +537,9 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp, |
|
|
|
|
exec_ctx, t, |
|
|
|
|
GRPC_ERROR_CREATE("Last stream closed after sending goaway")); |
|
|
|
|
} |
|
|
|
|
if (!t->executor.parsing_active && s->global.id) { |
|
|
|
|
GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map, |
|
|
|
|
s->global.id) == NULL); |
|
|
|
|
if (s->global.id != 0) { |
|
|
|
|
GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->global.id) == |
|
|
|
|
NULL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
while ( |
|
|
|
@ -597,8 +594,7 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, |
|
|
|
|
grpc_chttp2_stream_global *grpc_chttp2_parsing_lookup_stream( |
|
|
|
|
grpc_chttp2_transport_global *transport_global, uint32_t id) { |
|
|
|
|
grpc_chttp2_transport *t = TRANSPORT_FROM_GLOBAL(transport_global); |
|
|
|
|
grpc_chttp2_stream *s = |
|
|
|
|
grpc_chttp2_stream_map_find(&t->parsing_stream_map, id); |
|
|
|
|
grpc_chttp2_stream *s = grpc_chttp2_stream_map_find(&t->stream_map, id); |
|
|
|
|
return s ? &s->global : NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -879,7 +875,8 @@ static void maybe_start_some_streams( |
|
|
|
|
/* start streams where we have free grpc_chttp2_stream ids and free
|
|
|
|
|
* concurrency */ |
|
|
|
|
while (transport_global->next_stream_id <= MAX_CLIENT_STREAM_ID && |
|
|
|
|
transport_global->concurrent_stream_count < |
|
|
|
|
grpc_chttp2_stream_map_size( |
|
|
|
|
&TRANSPORT_FROM_GLOBAL(transport_global)->stream_map) < |
|
|
|
|
transport_global |
|
|
|
|
->settings[GRPC_PEER_SETTINGS] |
|
|
|
|
[GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS] && |
|
|
|
@ -910,10 +907,9 @@ static void maybe_start_some_streams( |
|
|
|
|
stream_global->max_recv_bytes = |
|
|
|
|
GPR_MAX(stream_incoming_window, stream_global->max_recv_bytes); |
|
|
|
|
grpc_chttp2_stream_map_add( |
|
|
|
|
&TRANSPORT_FROM_GLOBAL(transport_global)->new_stream_map, |
|
|
|
|
stream_global->id, STREAM_FROM_GLOBAL(stream_global)); |
|
|
|
|
&TRANSPORT_FROM_GLOBAL(transport_global)->stream_map, stream_global->id, |
|
|
|
|
STREAM_FROM_GLOBAL(stream_global)); |
|
|
|
|
stream_global->in_stream_map = true; |
|
|
|
|
transport_global->concurrent_stream_count++; |
|
|
|
|
grpc_chttp2_become_writable(exec_ctx, transport_global, stream_global, true, |
|
|
|
|
"new_stream"); |
|
|
|
|
} |
|
|
|
@ -1246,15 +1242,6 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx, |
|
|
|
|
grpc_chttp2_transport *t = op->transport_private.args[0]; |
|
|
|
|
grpc_error *close_transport = op->disconnect_with_error; |
|
|
|
|
|
|
|
|
|
/* If there's a set_accept_stream ensure that we're not parsing
|
|
|
|
|
to avoid changing things out from underneath */ |
|
|
|
|
if (t->executor.parsing_active && op->set_accept_stream) { |
|
|
|
|
GPR_ASSERT(t->post_parsing_op == NULL); |
|
|
|
|
t->post_parsing_op = gpr_malloc(sizeof(*op)); |
|
|
|
|
memcpy(t->post_parsing_op, op, sizeof(*op)); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (op->on_connectivity_state_change != NULL) { |
|
|
|
|
grpc_connectivity_state_notify_on_state_change( |
|
|
|
|
exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state, |
|
|
|
@ -1407,12 +1394,7 @@ static void decrement_active_streams_locked( |
|
|
|
|
|
|
|
|
|
static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, |
|
|
|
|
uint32_t id, grpc_error *error) { |
|
|
|
|
size_t new_stream_count; |
|
|
|
|
grpc_chttp2_stream *s = |
|
|
|
|
grpc_chttp2_stream_map_delete(&t->parsing_stream_map, id); |
|
|
|
|
if (!s) { |
|
|
|
|
s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id); |
|
|
|
|
} |
|
|
|
|
grpc_chttp2_stream *s = grpc_chttp2_stream_map_delete(&t->stream_map, id); |
|
|
|
|
GPR_ASSERT(s); |
|
|
|
|
s->global.in_stream_map = false; |
|
|
|
|
if (t->global.incoming_stream == &s->global) { |
|
|
|
@ -1435,14 +1417,9 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, |
|
|
|
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "chttp2_writing"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
new_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map) + |
|
|
|
|
grpc_chttp2_stream_map_size(&t->new_stream_map); |
|
|
|
|
GPR_ASSERT(new_stream_count <= UINT32_MAX); |
|
|
|
|
if (new_stream_count != t->global.concurrent_stream_count) { |
|
|
|
|
t->global.concurrent_stream_count = (uint32_t)new_stream_count; |
|
|
|
|
maybe_start_some_streams(exec_ctx, &t->global); |
|
|
|
|
} |
|
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
|
|
|
|
|
maybe_start_some_streams(exec_ctx, &t->global); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void status_codes_from_error(grpc_error *error, gpr_timespec deadline, |
|
|
|
@ -1627,18 +1604,12 @@ void grpc_chttp2_mark_stream_closed( |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (stream_global->read_closed && stream_global->write_closed) { |
|
|
|
|
if (stream_global->id != 0 && |
|
|
|
|
TRANSPORT_FROM_GLOBAL(transport_global)->executor.parsing_active) { |
|
|
|
|
grpc_chttp2_list_add_closed_waiting_for_parsing(transport_global, |
|
|
|
|
stream_global); |
|
|
|
|
} else { |
|
|
|
|
if (stream_global->id != 0) { |
|
|
|
|
remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global), |
|
|
|
|
stream_global->id, |
|
|
|
|
removal_error(GRPC_ERROR_REF(error), stream_global)); |
|
|
|
|
} |
|
|
|
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); |
|
|
|
|
if (stream_global->id != 0) { |
|
|
|
|
remove_stream(exec_ctx, TRANSPORT_FROM_GLOBAL(transport_global), |
|
|
|
|
stream_global->id, |
|
|
|
|
removal_error(GRPC_ERROR_REF(error), stream_global)); |
|
|
|
|
} |
|
|
|
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); |
|
|
|
|
} |
|
|
|
|
GRPC_ERROR_UNREF(error); |
|
|
|
|
} |
|
|
|
@ -1874,13 +1845,7 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, |
|
|
|
|
|
|
|
|
|
GRPC_ERROR_REF(error); |
|
|
|
|
|
|
|
|
|
GPR_ASSERT(!t->executor.parsing_active); |
|
|
|
|
if (!t->closed) { |
|
|
|
|
t->executor.parsing_active = 1; |
|
|
|
|
/* merge stream lists */ |
|
|
|
|
grpc_chttp2_stream_map_move_into(&t->new_stream_map, |
|
|
|
|
&t->parsing_stream_map); |
|
|
|
|
|
|
|
|
|
GPR_TIMER_BEGIN("reading_action.parse", 0); |
|
|
|
|
size_t i = 0; |
|
|
|
|
grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE, |
|
|
|
@ -1903,8 +1868,8 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, |
|
|
|
|
GPR_TIMER_BEGIN("post_parse_locked", 0); |
|
|
|
|
if (transport_global->initial_window_update != 0) { |
|
|
|
|
update_global_window_args args = {t, exec_ctx}; |
|
|
|
|
grpc_chttp2_stream_map_for_each(&t->parsing_stream_map, |
|
|
|
|
update_global_window, &args); |
|
|
|
|
grpc_chttp2_stream_map_for_each(&t->stream_map, update_global_window, |
|
|
|
|
&args); |
|
|
|
|
transport_global->initial_window_update = 0; |
|
|
|
|
} |
|
|
|
|
/* handle higher level things */ |
|
|
|
@ -1919,27 +1884,6 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx, void *tp, |
|
|
|
|
grpc_chttp2_initiate_write(exec_ctx, transport_global, false, |
|
|
|
|
"global incoming window"); |
|
|
|
|
} |
|
|
|
|
t->executor.parsing_active = 0; |
|
|
|
|
/* handle delayed transport ops (if there is one) */ |
|
|
|
|
if (t->post_parsing_op) { |
|
|
|
|
grpc_transport_op *op = t->post_parsing_op; |
|
|
|
|
t->post_parsing_op = NULL; |
|
|
|
|
perform_transport_op_locked(exec_ctx, op, GRPC_ERROR_NONE); |
|
|
|
|
gpr_free(op); |
|
|
|
|
} |
|
|
|
|
/* if a stream is in the stream map, and gets cancelled, we need to
|
|
|
|
|
* ensure we are not parsing before continuing the cancellation to keep |
|
|
|
|
* things in a sane state */ |
|
|
|
|
grpc_chttp2_stream_global *stream_global; |
|
|
|
|
while (grpc_chttp2_list_pop_closed_waiting_for_parsing(transport_global, |
|
|
|
|
&stream_global)) { |
|
|
|
|
GPR_ASSERT(stream_global->in_stream_map); |
|
|
|
|
GPR_ASSERT(stream_global->write_closed); |
|
|
|
|
GPR_ASSERT(stream_global->read_closed); |
|
|
|
|
remove_stream(exec_ctx, t, stream_global->id, |
|
|
|
|
removal_error(GRPC_ERROR_NONE, stream_global)); |
|
|
|
|
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GPR_TIMER_END("post_parse_locked", 0); |
|
|
|
|
} |
|
|
|
|