diff options
Diffstat (limited to 'src/core/ext/transport')
42 files changed, 1874 insertions, 1426 deletions
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index db5962e7fd..819f66aec3 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -61,34 +61,38 @@ static void chttp2_connector_ref(grpc_connector* con) { gpr_ref(&c->refs); } -static void chttp2_connector_unref(grpc_connector* con) { +static void chttp2_connector_unref(grpc_exec_ctx* exec_ctx, + grpc_connector* con) { chttp2_connector* c = (chttp2_connector*)con; if (gpr_unref(&c->refs)) { gpr_mu_destroy(&c->mu); // If handshaking is not yet in progress, destroy the endpoint. // Otherwise, the handshaker will do this for us. - if (c->endpoint != nullptr) grpc_endpoint_destroy(c->endpoint); + if (c->endpoint != nullptr) grpc_endpoint_destroy(exec_ctx, c->endpoint); gpr_free(c); } } -static void chttp2_connector_shutdown(grpc_connector* con, grpc_error* why) { +static void chttp2_connector_shutdown(grpc_exec_ctx* exec_ctx, + grpc_connector* con, grpc_error* why) { chttp2_connector* c = (chttp2_connector*)con; gpr_mu_lock(&c->mu); c->shutdown = true; if (c->handshake_mgr != nullptr) { - grpc_handshake_manager_shutdown(c->handshake_mgr, GRPC_ERROR_REF(why)); + grpc_handshake_manager_shutdown(exec_ctx, c->handshake_mgr, + GRPC_ERROR_REF(why)); } // If handshaking is not yet in progress, shutdown the endpoint. // Otherwise, the handshaker will do this for us. if (!c->connecting && c->endpoint != nullptr) { - grpc_endpoint_shutdown(c->endpoint, GRPC_ERROR_REF(why)); + grpc_endpoint_shutdown(exec_ctx, c->endpoint, GRPC_ERROR_REF(why)); } gpr_mu_unlock(&c->mu); GRPC_ERROR_UNREF(why); } -static void on_handshake_done(void* arg, grpc_error* error) { +static void on_handshake_done(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { grpc_handshaker_args* args = (grpc_handshaker_args*)arg; chttp2_connector* c = (chttp2_connector*)args->user_data; gpr_mu_lock(&c->mu); @@ -101,20 +105,20 @@ static void on_handshake_done(void* arg, grpc_error* error) { // before destroying them, even if we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. - grpc_endpoint_shutdown(args->endpoint, GRPC_ERROR_REF(error)); - grpc_endpoint_destroy(args->endpoint); - grpc_channel_args_destroy(args->args); - grpc_slice_buffer_destroy_internal(args->read_buffer); + grpc_endpoint_shutdown(exec_ctx, args->endpoint, GRPC_ERROR_REF(error)); + grpc_endpoint_destroy(exec_ctx, args->endpoint); + grpc_channel_args_destroy(exec_ctx, args->args); + grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer); gpr_free(args->read_buffer); } else { error = GRPC_ERROR_REF(error); } memset(c->result, 0, sizeof(*c->result)); } else { - grpc_endpoint_delete_from_pollset_set(args->endpoint, + grpc_endpoint_delete_from_pollset_set(exec_ctx, args->endpoint, c->args.interested_parties); - c->result->transport = - grpc_create_chttp2_transport(args->args, args->endpoint, true); + c->result->transport = grpc_create_chttp2_transport(exec_ctx, args->args, + args->endpoint, true); GPR_ASSERT(c->result->transport); // TODO(roth): We ideally want to wait until we receive HTTP/2 // settings from the server before we consider the connection @@ -140,32 +144,34 @@ static void on_handshake_done(void* arg, grpc_error* error) { // so until after transparent retries is implemented. Otherwise, any // RPC that we attempt to send on the connection before the timeout // would fail instead of being retried on a subsequent attempt. - grpc_chttp2_transport_start_reading(c->result->transport, args->read_buffer, - nullptr); + grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, + args->read_buffer, nullptr); c->result->channel_args = args->args; } grpc_closure* notify = c->notify; c->notify = nullptr; - GRPC_CLOSURE_SCHED(notify, error); - grpc_handshake_manager_destroy(c->handshake_mgr); + GRPC_CLOSURE_SCHED(exec_ctx, notify, error); + grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); c->handshake_mgr = nullptr; gpr_mu_unlock(&c->mu); - chttp2_connector_unref((grpc_connector*)c); + chttp2_connector_unref(exec_ctx, (grpc_connector*)c); } -static void start_handshake_locked(chttp2_connector* c) { +static void start_handshake_locked(grpc_exec_ctx* exec_ctx, + chttp2_connector* c) { c->handshake_mgr = grpc_handshake_manager_create(); - grpc_handshakers_add(HANDSHAKER_CLIENT, c->args.channel_args, + grpc_handshakers_add(exec_ctx, HANDSHAKER_CLIENT, c->args.channel_args, c->handshake_mgr); - grpc_endpoint_add_to_pollset_set(c->endpoint, c->args.interested_parties); + grpc_endpoint_add_to_pollset_set(exec_ctx, c->endpoint, + c->args.interested_parties); grpc_handshake_manager_do_handshake( - c->handshake_mgr, c->args.interested_parties, c->endpoint, + exec_ctx, c->handshake_mgr, c->args.interested_parties, c->endpoint, c->args.channel_args, c->args.deadline, nullptr /* acceptor */, on_handshake_done, c); c->endpoint = nullptr; // Endpoint handed off to handshake manager. } -static void connected(void* arg, grpc_error* error) { +static void connected(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) { chttp2_connector* c = (chttp2_connector*)arg; gpr_mu_lock(&c->mu); GPR_ASSERT(c->connecting); @@ -179,26 +185,27 @@ static void connected(void* arg, grpc_error* error) { memset(c->result, 0, sizeof(*c->result)); grpc_closure* notify = c->notify; c->notify = nullptr; - GRPC_CLOSURE_SCHED(notify, error); + GRPC_CLOSURE_SCHED(exec_ctx, notify, error); if (c->endpoint != nullptr) { - grpc_endpoint_shutdown(c->endpoint, GRPC_ERROR_REF(error)); + grpc_endpoint_shutdown(exec_ctx, c->endpoint, GRPC_ERROR_REF(error)); } gpr_mu_unlock(&c->mu); - chttp2_connector_unref((grpc_connector*)arg); + chttp2_connector_unref(exec_ctx, (grpc_connector*)arg); } else { GPR_ASSERT(c->endpoint != nullptr); - start_handshake_locked(c); + start_handshake_locked(exec_ctx, c); gpr_mu_unlock(&c->mu); } } -static void chttp2_connector_connect(grpc_connector* con, +static void chttp2_connector_connect(grpc_exec_ctx* exec_ctx, + grpc_connector* con, const grpc_connect_in_args* args, grpc_connect_out_args* result, grpc_closure* notify) { chttp2_connector* c = (chttp2_connector*)con; grpc_resolved_address addr; - grpc_get_subchannel_address_arg(args->channel_args, &addr); + grpc_get_subchannel_address_arg(exec_ctx, args->channel_args, &addr); gpr_mu_lock(&c->mu); GPR_ASSERT(c->notify == nullptr); c->notify = notify; @@ -209,8 +216,9 @@ static void chttp2_connector_connect(grpc_connector* con, GRPC_CLOSURE_INIT(&c->connected, connected, c, grpc_schedule_on_exec_ctx); GPR_ASSERT(!c->connecting); c->connecting = true; - grpc_tcp_client_connect(&c->connected, &c->endpoint, args->interested_parties, - args->channel_args, &addr, args->deadline); + grpc_tcp_client_connect(exec_ctx, &c->connected, &c->endpoint, + args->interested_parties, args->channel_args, &addr, + args->deadline); gpr_mu_unlock(&c->mu); } diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index 6a1b70964d..028b69e5ff 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -34,19 +34,21 @@ static void client_channel_factory_ref( grpc_client_channel_factory* cc_factory) {} static void client_channel_factory_unref( - grpc_client_channel_factory* cc_factory) {} + grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* cc_factory) {} static grpc_subchannel* client_channel_factory_create_subchannel( - grpc_client_channel_factory* cc_factory, const grpc_subchannel_args* args) { + grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* cc_factory, + const grpc_subchannel_args* args) { grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_subchannel* s = grpc_subchannel_create(connector, args); - grpc_connector_unref(connector); + grpc_subchannel* s = grpc_subchannel_create(exec_ctx, connector, args); + grpc_connector_unref(exec_ctx, connector); return s; } static grpc_channel* client_channel_factory_create_channel( - grpc_client_channel_factory* cc_factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args) { + grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* cc_factory, + const char* target, grpc_client_channel_type type, + const grpc_channel_args* args) { if (target == nullptr) { gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); return nullptr; @@ -54,14 +56,14 @@ static grpc_channel* client_channel_factory_create_channel( // Add channel arg containing the server URI. grpc_arg arg = grpc_channel_arg_string_create( (char*)GRPC_ARG_SERVER_URI, - grpc_resolver_factory_add_default_prefix_if_needed(target)); + grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target)); const char* to_remove[] = {GRPC_ARG_SERVER_URI}; grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); gpr_free(arg.value.string); - grpc_channel* channel = - grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); - grpc_channel_args_destroy(new_args); + grpc_channel* channel = grpc_channel_create(exec_ctx, target, new_args, + GRPC_CLIENT_CHANNEL, nullptr); + grpc_channel_args_destroy(exec_ctx, new_args); return channel; } @@ -80,7 +82,7 @@ static grpc_client_channel_factory client_channel_factory = { grpc_channel* grpc_insecure_channel_create(const char* target, const grpc_channel_args* args, void* reserved) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_API_TRACE( "grpc_insecure_channel_create(target=%s, args=%p, reserved=%p)", 3, (target, args, reserved)); @@ -91,11 +93,11 @@ grpc_channel* grpc_insecure_channel_create(const char* target, grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &arg, 1); // Create channel. grpc_channel* channel = client_channel_factory_create_channel( - &client_channel_factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, - new_args); + &exec_ctx, &client_channel_factory, target, + GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args); // Clean up. - grpc_channel_args_destroy(new_args); - + grpc_channel_args_destroy(&exec_ctx, new_args); + grpc_exec_ctx_finish(&exec_ctx); return channel != nullptr ? channel : grpc_lame_client_channel_create( target, GRPC_STATUS_INTERNAL, diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc index 0cdea5a94e..c6b149d0b1 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc @@ -37,7 +37,7 @@ grpc_channel* grpc_insecure_channel_create_from_fd( const char* target, int fd, const grpc_channel_args* args) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_API_TRACE("grpc_insecure_channel_create(target=%p, fd=%d, args=%p)", 3, (target, fd, args)); @@ -50,17 +50,17 @@ grpc_channel* grpc_insecure_channel_create_from_fd( GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0); grpc_endpoint* client = grpc_tcp_client_create_from_fd( - grpc_fd_create(fd, "client"), args, "fd-client"); + &exec_ctx, grpc_fd_create(fd, "client"), args, "fd-client"); grpc_transport* transport = - grpc_create_chttp2_transport(final_args, client, true); + grpc_create_chttp2_transport(&exec_ctx, final_args, client, true); GPR_ASSERT(transport); grpc_channel* channel = grpc_channel_create( - target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); - grpc_channel_args_destroy(final_args); - grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); + &exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); + grpc_channel_args_destroy(&exec_ctx, final_args); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, nullptr, nullptr); - grpc_core::ExecCtx::Get()->Flush(); + grpc_exec_ctx_finish(&exec_ctx); return channel != nullptr ? channel : grpc_lame_client_channel_create( @@ -73,7 +73,7 @@ grpc_channel* grpc_insecure_channel_create_from_fd( grpc_channel* grpc_insecure_channel_create_from_fd( const char* target, int fd, const grpc_channel_args* args) { GPR_ASSERT(0); - return nullptr; + return NULL; } #endif // GPR_SUPPORT_CHANNELS_FROM_FD diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index 27c5b96a4c..dd2bc427a7 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -41,10 +41,10 @@ static void client_channel_factory_ref( grpc_client_channel_factory* cc_factory) {} static void client_channel_factory_unref( - grpc_client_channel_factory* cc_factory) {} + grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* cc_factory) {} static grpc_subchannel_args* get_secure_naming_subchannel_args( - const grpc_subchannel_args* args) { + grpc_exec_ctx* exec_ctx, const grpc_subchannel_args* args) { grpc_channel_credentials* channel_credentials = grpc_channel_credentials_find_in_args(args->args); if (channel_credentials == nullptr) { @@ -68,7 +68,7 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( const char* server_uri_str = server_uri_arg->value.string; GPR_ASSERT(server_uri_str != nullptr); grpc_uri* server_uri = - grpc_uri_parse(server_uri_str, true /* supress errors */); + grpc_uri_parse(exec_ctx, server_uri_str, true /* supress errors */); GPR_ASSERT(server_uri != nullptr); const char* server_uri_path; server_uri_path = @@ -81,7 +81,7 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( const char* target_uri_str = grpc_get_subchannel_address_uri_arg(args->args); grpc_uri* target_uri = - grpc_uri_parse(target_uri_str, false /* suppress errors */); + grpc_uri_parse(exec_ctx, target_uri_str, false /* suppress errors */); GPR_ASSERT(target_uri != nullptr); if (target_uri->path[0] != '\0') { // "path" may be empty const grpc_slice key = grpc_slice_from_static_string( @@ -89,7 +89,7 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( const char* value = (const char*)grpc_slice_hash_table_get(targets_info, key); if (value != nullptr) target_name_to_check = gpr_strdup(value); - grpc_slice_unref_internal(key); + grpc_slice_unref_internal(exec_ctx, key); } if (target_name_to_check == nullptr) { // If the target name to check hasn't already been set, fall back to using @@ -107,7 +107,7 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( grpc_channel_args* new_args_from_connector = nullptr; const grpc_security_status security_status = grpc_channel_credentials_create_security_connector( - channel_credentials, target_name_to_check, args->args, + exec_ctx, channel_credentials, target_name_to_check, args->args, &subchannel_security_connector, &new_args_from_connector); if (security_status != GRPC_SECURITY_OK) { gpr_log(GPR_ERROR, @@ -123,10 +123,10 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( grpc_channel_args* new_args = grpc_channel_args_copy_and_add( new_args_from_connector != nullptr ? new_args_from_connector : args->args, &new_security_connector_arg, 1); - GRPC_SECURITY_CONNECTOR_UNREF(&subchannel_security_connector->base, + GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &subchannel_security_connector->base, "lb_channel_create"); if (new_args_from_connector != nullptr) { - grpc_channel_args_destroy(new_args_from_connector); + grpc_channel_args_destroy(exec_ctx, new_args_from_connector); } grpc_subchannel_args* final_sc_args = (grpc_subchannel_args*)gpr_malloc(sizeof(*final_sc_args)); @@ -136,9 +136,10 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args( } static grpc_subchannel* client_channel_factory_create_subchannel( - grpc_client_channel_factory* cc_factory, const grpc_subchannel_args* args) { + grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* cc_factory, + const grpc_subchannel_args* args) { grpc_subchannel_args* subchannel_args = - get_secure_naming_subchannel_args(args); + get_secure_naming_subchannel_args(exec_ctx, args); if (subchannel_args == nullptr) { gpr_log( GPR_ERROR, @@ -146,16 +147,19 @@ static grpc_subchannel* client_channel_factory_create_subchannel( return nullptr; } grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_subchannel* s = grpc_subchannel_create(connector, subchannel_args); - grpc_connector_unref(connector); - grpc_channel_args_destroy((grpc_channel_args*)subchannel_args->args); + grpc_subchannel* s = + grpc_subchannel_create(exec_ctx, connector, subchannel_args); + grpc_connector_unref(exec_ctx, connector); + grpc_channel_args_destroy(exec_ctx, + (grpc_channel_args*)subchannel_args->args); gpr_free(subchannel_args); return s; } static grpc_channel* client_channel_factory_create_channel( - grpc_client_channel_factory* cc_factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args) { + grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* cc_factory, + const char* target, grpc_client_channel_type type, + const grpc_channel_args* args) { if (target == nullptr) { gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); return nullptr; @@ -163,14 +167,14 @@ static grpc_channel* client_channel_factory_create_channel( // Add channel arg containing the server URI. grpc_arg arg = grpc_channel_arg_string_create( (char*)GRPC_ARG_SERVER_URI, - grpc_resolver_factory_add_default_prefix_if_needed(target)); + grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target)); const char* to_remove[] = {GRPC_ARG_SERVER_URI}; grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); gpr_free(arg.value.string); - grpc_channel* channel = - grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); - grpc_channel_args_destroy(new_args); + grpc_channel* channel = grpc_channel_create(exec_ctx, target, new_args, + GRPC_CLIENT_CHANNEL, nullptr); + grpc_channel_args_destroy(exec_ctx, new_args); return channel; } @@ -190,7 +194,7 @@ grpc_channel* grpc_secure_channel_create(grpc_channel_credentials* creds, const char* target, const grpc_channel_args* args, void* reserved) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_API_TRACE( "grpc_secure_channel_create(creds=%p, target=%s, args=%p, " "reserved=%p)", @@ -207,10 +211,11 @@ grpc_channel* grpc_secure_channel_create(grpc_channel_credentials* creds, args, args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Create channel. channel = client_channel_factory_create_channel( - &client_channel_factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, - new_args); + &exec_ctx, &client_channel_factory, target, + GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args); // Clean up. - grpc_channel_args_destroy(new_args); + grpc_channel_args_destroy(&exec_ctx, new_args); + grpc_exec_ctx_finish(&exec_ctx); } return channel != nullptr ? channel : grpc_lame_client_channel_create( diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 5669fa4090..49ee677464 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -69,17 +69,17 @@ typedef struct { } server_connection_state; static void server_connection_state_unref( - server_connection_state* connection_state) { + grpc_exec_ctx* exec_ctx, server_connection_state* connection_state) { if (gpr_unref(&connection_state->refs)) { if (connection_state->transport != nullptr) { - GRPC_CHTTP2_UNREF_TRANSPORT(connection_state->transport, + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, connection_state->transport, "receive settings timeout"); } gpr_free(connection_state); } } -static void on_timeout(void* arg, grpc_error* error) { +static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) { server_connection_state* connection_state = (server_connection_state*)arg; // Note that we may be called with GRPC_ERROR_NONE when the timer fires // or with an error indicating that the timer system is being shut down. @@ -87,20 +87,22 @@ static void on_timeout(void* arg, grpc_error* error) { grpc_transport_op* op = grpc_make_transport_op(nullptr); op->disconnect_with_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Did not receive HTTP/2 settings before handshake timeout"); - grpc_transport_perform_op(&connection_state->transport->base, op); + grpc_transport_perform_op(exec_ctx, &connection_state->transport->base, op); } - server_connection_state_unref(connection_state); + server_connection_state_unref(exec_ctx, connection_state); } -static void on_receive_settings(void* arg, grpc_error* error) { +static void on_receive_settings(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { server_connection_state* connection_state = (server_connection_state*)arg; if (error == GRPC_ERROR_NONE) { - grpc_timer_cancel(&connection_state->timer); + grpc_timer_cancel(exec_ctx, &connection_state->timer); } - server_connection_state_unref(connection_state); + server_connection_state_unref(exec_ctx, connection_state); } -static void on_handshake_done(void* arg, grpc_error* error) { +static void on_handshake_done(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { grpc_handshaker_args* args = (grpc_handshaker_args*)arg; server_connection_state* connection_state = (server_connection_state*)args->user_data; @@ -115,10 +117,10 @@ static void on_handshake_done(void* arg, grpc_error* error) { // before destroying them, even if we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. - grpc_endpoint_shutdown(args->endpoint, GRPC_ERROR_NONE); - grpc_endpoint_destroy(args->endpoint); - grpc_channel_args_destroy(args->args); - grpc_slice_buffer_destroy_internal(args->read_buffer); + grpc_endpoint_shutdown(exec_ctx, args->endpoint, GRPC_ERROR_NONE); + grpc_endpoint_destroy(exec_ctx, args->endpoint); + grpc_channel_args_destroy(exec_ctx, args->args); + grpc_slice_buffer_destroy_internal(exec_ctx, args->read_buffer); gpr_free(args->read_buffer); } } else { @@ -126,10 +128,10 @@ static void on_handshake_done(void* arg, grpc_error* error) { // handshaker may have handed off the connection to some external // code, so we can just clean up here without creating a transport. if (args->endpoint != nullptr) { - grpc_transport* transport = - grpc_create_chttp2_transport(args->args, args->endpoint, false); + grpc_transport* transport = grpc_create_chttp2_transport( + exec_ctx, args->args, args->endpoint, false); grpc_server_setup_transport( - connection_state->svr_state->server, transport, + exec_ctx, connection_state->svr_state->server, transport, connection_state->accepting_pollset, args->args); // Use notify_on_receive_settings callback to enforce the // handshake deadline. @@ -139,14 +141,16 @@ static void on_handshake_done(void* arg, grpc_error* error) { on_receive_settings, connection_state, grpc_schedule_on_exec_ctx); grpc_chttp2_transport_start_reading( - transport, args->read_buffer, &connection_state->on_receive_settings); - grpc_channel_args_destroy(args->args); + exec_ctx, transport, args->read_buffer, + &connection_state->on_receive_settings); + grpc_channel_args_destroy(exec_ctx, args->args); gpr_ref(&connection_state->refs); GRPC_CHTTP2_REF_TRANSPORT((grpc_chttp2_transport*)transport, "receive settings timeout"); GRPC_CLOSURE_INIT(&connection_state->on_timeout, on_timeout, connection_state, grpc_schedule_on_exec_ctx); - grpc_timer_init(&connection_state->timer, connection_state->deadline, + grpc_timer_init(exec_ctx, &connection_state->timer, + connection_state->deadline, &connection_state->on_timeout); } } @@ -154,21 +158,21 @@ static void on_handshake_done(void* arg, grpc_error* error) { &connection_state->svr_state->pending_handshake_mgrs, connection_state->handshake_mgr); gpr_mu_unlock(&connection_state->svr_state->mu); - grpc_handshake_manager_destroy(connection_state->handshake_mgr); + grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr); gpr_free(connection_state->acceptor); - grpc_tcp_server_unref(connection_state->svr_state->tcp_server); - server_connection_state_unref(connection_state); + grpc_tcp_server_unref(exec_ctx, connection_state->svr_state->tcp_server); + server_connection_state_unref(exec_ctx, connection_state); } -static void on_accept(void* arg, grpc_endpoint* tcp, +static void on_accept(grpc_exec_ctx* exec_ctx, void* arg, grpc_endpoint* tcp, grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor) { server_state* state = (server_state*)arg; gpr_mu_lock(&state->mu); if (state->shutdown) { gpr_mu_unlock(&state->mu); - grpc_endpoint_shutdown(tcp, GRPC_ERROR_NONE); - grpc_endpoint_destroy(tcp); + grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_NONE); + grpc_endpoint_destroy(exec_ctx, tcp); gpr_free(acceptor); return; } @@ -184,56 +188,59 @@ static void on_accept(void* arg, grpc_endpoint* tcp, connection_state->accepting_pollset = accepting_pollset; connection_state->acceptor = acceptor; connection_state->handshake_mgr = handshake_mgr; - grpc_handshakers_add(HANDSHAKER_SERVER, state->args, + grpc_handshakers_add(exec_ctx, HANDSHAKER_SERVER, state->args, connection_state->handshake_mgr); const grpc_arg* timeout_arg = grpc_channel_args_find(state->args, GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS); connection_state->deadline = - grpc_core::ExecCtx::Get()->Now() + + grpc_exec_ctx_now(exec_ctx) + grpc_channel_arg_get_integer(timeout_arg, {120 * GPR_MS_PER_SEC, 1, INT_MAX}); - grpc_handshake_manager_do_handshake( - connection_state->handshake_mgr, nullptr /* interested_parties */, tcp, - state->args, connection_state->deadline, acceptor, on_handshake_done, - connection_state); + grpc_handshake_manager_do_handshake(exec_ctx, connection_state->handshake_mgr, + nullptr /* interested_parties */, tcp, + state->args, connection_state->deadline, + acceptor, on_handshake_done, + connection_state); } /* Server callback: start listening on our ports */ -static void server_start_listener(grpc_server* server, void* arg, - grpc_pollset** pollsets, +static void server_start_listener(grpc_exec_ctx* exec_ctx, grpc_server* server, + void* arg, grpc_pollset** pollsets, size_t pollset_count) { server_state* state = (server_state*)arg; gpr_mu_lock(&state->mu); state->shutdown = false; gpr_mu_unlock(&state->mu); - grpc_tcp_server_start(state->tcp_server, pollsets, pollset_count, on_accept, - state); + grpc_tcp_server_start(exec_ctx, state->tcp_server, pollsets, pollset_count, + on_accept, state); } -static void tcp_server_shutdown_complete(void* arg, grpc_error* error) { +static void tcp_server_shutdown_complete(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { server_state* state = (server_state*)arg; /* ensure all threads have unlocked */ gpr_mu_lock(&state->mu); grpc_closure* destroy_done = state->server_destroy_listener_done; GPR_ASSERT(state->shutdown); grpc_handshake_manager_pending_list_shutdown_all( - state->pending_handshake_mgrs, GRPC_ERROR_REF(error)); + exec_ctx, state->pending_handshake_mgrs, GRPC_ERROR_REF(error)); gpr_mu_unlock(&state->mu); // Flush queued work before destroying handshaker factory, since that // may do a synchronous unref. - grpc_core::ExecCtx::Get()->Flush(); + grpc_exec_ctx_flush(exec_ctx); if (destroy_done != nullptr) { - destroy_done->cb(destroy_done->cb_arg, GRPC_ERROR_REF(error)); - grpc_core::ExecCtx::Get()->Flush(); + destroy_done->cb(exec_ctx, destroy_done->cb_arg, GRPC_ERROR_REF(error)); + grpc_exec_ctx_flush(exec_ctx); } - grpc_channel_args_destroy(state->args); + grpc_channel_args_destroy(exec_ctx, state->args); gpr_mu_destroy(&state->mu); gpr_free(state); } /* Server callback: destroy the tcp listener (so we don't generate further callbacks) */ -static void server_destroy_listener(grpc_server* server, void* arg, +static void server_destroy_listener(grpc_exec_ctx* exec_ctx, + grpc_server* server, void* arg, grpc_closure* destroy_done) { server_state* state = (server_state*)arg; gpr_mu_lock(&state->mu); @@ -241,11 +248,12 @@ static void server_destroy_listener(grpc_server* server, void* arg, state->server_destroy_listener_done = destroy_done; grpc_tcp_server* tcp_server = state->tcp_server; gpr_mu_unlock(&state->mu); - grpc_tcp_server_shutdown_listeners(tcp_server); - grpc_tcp_server_unref(tcp_server); + grpc_tcp_server_shutdown_listeners(exec_ctx, tcp_server); + grpc_tcp_server_unref(exec_ctx, tcp_server); } -grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr, +grpc_error* grpc_chttp2_server_add_port(grpc_exec_ctx* exec_ctx, + grpc_server* server, const char* addr, grpc_channel_args* args, int* port_num) { grpc_resolved_addresses* resolved = nullptr; @@ -269,8 +277,8 @@ grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr, GRPC_CLOSURE_INIT(&state->tcp_server_shutdown_complete, tcp_server_shutdown_complete, state, grpc_schedule_on_exec_ctx); - err = grpc_tcp_server_create(&state->tcp_server_shutdown_complete, args, - &tcp_server); + err = grpc_tcp_server_create(exec_ctx, &state->tcp_server_shutdown_complete, + args, &tcp_server); if (err != GRPC_ERROR_NONE) { goto error; } @@ -319,7 +327,7 @@ grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr, grpc_resolved_addresses_destroy(resolved); /* Register with the server only upon success */ - grpc_server_add_listener(server, state, server_start_listener, + grpc_server_add_listener(exec_ctx, server, state, server_start_listener, server_destroy_listener); goto done; @@ -330,9 +338,9 @@ error: grpc_resolved_addresses_destroy(resolved); } if (tcp_server) { - grpc_tcp_server_unref(tcp_server); + grpc_tcp_server_unref(exec_ctx, tcp_server); } else { - grpc_channel_args_destroy(args); + grpc_channel_args_destroy(exec_ctx, args); gpr_free(state); } *port_num = 0; diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.h b/src/core/ext/transport/chttp2/server/chttp2_server.h index 7de859da42..68304fd4f7 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.h +++ b/src/core/ext/transport/chttp2/server/chttp2_server.h @@ -25,7 +25,8 @@ /// Adds a port to \a server. Sets \a port_num to the port number. /// Takes ownership of \a args. -grpc_error* grpc_chttp2_server_add_port(grpc_server* server, const char* addr, +grpc_error* grpc_chttp2_server_add_port(grpc_exec_ctx* exec_ctx, + grpc_server* server, const char* addr, grpc_channel_args* args, int* port_num); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H */ diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc index 52c42d056c..8984896538 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc @@ -26,12 +26,12 @@ #include "src/core/lib/surface/server.h" int grpc_server_add_insecure_http2_port(grpc_server* server, const char* addr) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; int port_num = 0; GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2, (server, addr)); grpc_error* err = grpc_chttp2_server_add_port( - server, addr, + &exec_ctx, server, addr, grpc_channel_args_copy(grpc_server_get_channel_args(server)), &port_num); if (err != GRPC_ERROR_NONE) { const char* msg = grpc_error_string(err); @@ -39,6 +39,6 @@ int grpc_server_add_insecure_http2_port(grpc_server* server, const char* addr) { GRPC_ERROR_UNREF(err); } - + grpc_exec_ctx_finish(&exec_ctx); return port_num; } diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc index dafd4af6ce..3fe05ce4ef 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc @@ -38,29 +38,32 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server, void* reserved, int fd) { GPR_ASSERT(reserved == nullptr); - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; char* name; gpr_asprintf(&name, "fd:%d", fd); - grpc_endpoint* server_endpoint = grpc_tcp_create( - grpc_fd_create(fd, name), grpc_server_get_channel_args(server), name); + grpc_endpoint* server_endpoint = + grpc_tcp_create(&exec_ctx, grpc_fd_create(fd, name), + grpc_server_get_channel_args(server), name); gpr_free(name); const grpc_channel_args* server_args = grpc_server_get_channel_args(server); grpc_transport* transport = grpc_create_chttp2_transport( - server_args, server_endpoint, false /* is_client */); + &exec_ctx, server_args, server_endpoint, false /* is_client */); grpc_pollset** pollsets; size_t num_pollsets = 0; grpc_server_get_pollsets(server, &pollsets, &num_pollsets); for (size_t i = 0; i < num_pollsets; i++) { - grpc_endpoint_add_to_pollset(server_endpoint, pollsets[i]); + grpc_endpoint_add_to_pollset(&exec_ctx, server_endpoint, pollsets[i]); } - grpc_server_setup_transport(server, transport, nullptr, server_args); - grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); + grpc_server_setup_transport(&exec_ctx, server, transport, nullptr, + server_args); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, nullptr, nullptr); + grpc_exec_ctx_finish(&exec_ctx); } #else // !GPR_SUPPORT_CHANNELS_FROM_FD diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc index 723af97ff0..ac3ea40f47 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc @@ -36,7 +36,7 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr, grpc_server_credentials* creds) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_error* err = GRPC_ERROR_NONE; grpc_server_security_connector* sc = nullptr; int port_num = 0; @@ -52,7 +52,8 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr, "No credentials specified for secure server port (creds==NULL)"); goto done; } - status = grpc_server_credentials_create_security_connector(creds, &sc); + status = + grpc_server_credentials_create_security_connector(&exec_ctx, creds, &sc); if (status != GRPC_SECURITY_OK) { char* msg; gpr_asprintf(&msg, @@ -71,12 +72,12 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr, grpc_channel_args_copy_and_add(grpc_server_get_channel_args(server), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Add server port. - err = grpc_chttp2_server_add_port(server, addr, args, &port_num); + err = grpc_chttp2_server_add_port(&exec_ctx, server, addr, args, &port_num); done: if (sc != nullptr) { - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server"); + GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &sc->base, "server"); } - + grpc_exec_ctx_finish(&exec_ctx); if (err != GRPC_ERROR_NONE) { const char* msg = grpc_error_string(err); gpr_log(GPR_ERROR, "%s", msg); diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.cc b/src/core/ext/transport/chttp2/transport/bin_decoder.cc index 984cd4ca78..3ccae7afc3 100644 --- a/src/core/ext/transport/chttp2/transport/bin_decoder.cc +++ b/src/core/ext/transport/chttp2/transport/bin_decoder.cc @@ -130,7 +130,8 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context* ctx) { return true; } -grpc_slice grpc_chttp2_base64_decode(grpc_slice input) { +grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx* exec_ctx, + grpc_slice input) { size_t input_length = GRPC_SLICE_LENGTH(input); size_t output_length = input_length / 4 * 3; struct grpc_base64_decode_context ctx; @@ -166,7 +167,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) { char* s = grpc_slice_to_c_string(input); gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s); gpr_free(s); - grpc_slice_unref_internal(output); + grpc_slice_unref_internal(exec_ctx, output); return grpc_empty_slice(); } GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output)); @@ -174,7 +175,8 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) { return output; } -grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input, +grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx* exec_ctx, + grpc_slice input, size_t output_length) { size_t input_length = GRPC_SLICE_LENGTH(input); grpc_slice output = GRPC_SLICE_MALLOC(output_length); @@ -187,7 +189,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input, "grpc_chttp2_base64_decode_with_length has a length of %d, which " "has a tail of 1 byte.\n", (int)input_length); - grpc_slice_unref_internal(output); + grpc_slice_unref_internal(exec_ctx, output); return grpc_empty_slice(); } @@ -197,7 +199,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input, "than the max possible output length %d.\n", (int)output_length, (int)(input_length / 4 * 3 + tail_xtra[input_length % 4])); - grpc_slice_unref_internal(output); + grpc_slice_unref_internal(exec_ctx, output); return grpc_empty_slice(); } @@ -211,7 +213,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input, char* s = grpc_slice_to_c_string(input); gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s); gpr_free(s); - grpc_slice_unref_internal(output); + grpc_slice_unref_internal(exec_ctx, output); return grpc_empty_slice(); } GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output)); diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.h b/src/core/ext/transport/chttp2/transport/bin_decoder.h index 9cb75ccd81..a78c305766 100644 --- a/src/core/ext/transport/chttp2/transport/bin_decoder.h +++ b/src/core/ext/transport/chttp2/transport/bin_decoder.h @@ -40,12 +40,13 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context* ctx); /* base64 decode a slice with pad chars. Returns a new slice, does not take ownership of the input. Returns an empty slice if decoding is failed. */ -grpc_slice grpc_chttp2_base64_decode(grpc_slice input); +grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx* exec_ctx, grpc_slice input); /* base64 decode a slice without pad chars, data length is needed. Returns a new slice, does not take ownership of the input. Returns an empty slice if decoding is failed. */ -grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input, +grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx* exec_ctx, + grpc_slice input, size_t output_length); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H */ diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.h b/src/core/ext/transport/chttp2/transport/bin_encoder.h index 93ad0dfdea..a8f36a345a 100644 --- a/src/core/ext/transport/chttp2/transport/bin_encoder.h +++ b/src/core/ext/transport/chttp2/transport/bin_encoder.h @@ -32,7 +32,7 @@ grpc_slice grpc_chttp2_huffman_compress(grpc_slice input); /* equivalent to: grpc_slice x = grpc_chttp2_base64_encode(input); grpc_slice y = grpc_chttp2_huffman_compress(x); - grpc_slice_unref_internal( x); + grpc_slice_unref_internal(exec_ctx, x); return y; */ grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input); diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index f537fb09c2..63ac65ac78 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -95,77 +95,105 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_chttp2_refcount(false, "chttp2_refcount"); /* forward declarations of various callbacks that we'll build closures around */ -static void write_action_begin_locked(void* t, grpc_error* error); -static void write_action(void* t, grpc_error* error); -static void write_action_end_locked(void* t, grpc_error* error); +static void write_action_begin_locked(grpc_exec_ctx* exec_ctx, void* t, + grpc_error* error); +static void write_action(grpc_exec_ctx* exec_ctx, void* t, grpc_error* error); +static void write_action_end_locked(grpc_exec_ctx* exec_ctx, void* t, + grpc_error* error); -static void read_action_locked(void* t, grpc_error* error); +static void read_action_locked(grpc_exec_ctx* exec_ctx, void* t, + grpc_error* error); -static void complete_fetch_locked(void* gs, grpc_error* error); +static void complete_fetch_locked(grpc_exec_ctx* exec_ctx, void* gs, + grpc_error* error); /** Set a transport level setting, and push it to our peer */ -static void queue_setting_update(grpc_chttp2_transport* t, +static void queue_setting_update(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_setting_id id, uint32_t value); -static void close_from_api(grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_error* error); +static void close_from_api(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_chttp2_stream* s, grpc_error* error); /** Start new streams that have been created if we can */ -static void maybe_start_some_streams(grpc_chttp2_transport* t); +static void maybe_start_some_streams(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); -static void connectivity_state_set(grpc_chttp2_transport* t, +static void connectivity_state_set(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_connectivity_state state, grpc_error* error, const char* reason); -static void incoming_byte_stream_destroy_locked(void* byte_stream, +static void incoming_byte_stream_destroy_locked(grpc_exec_ctx* exec_ctx, + void* byte_stream, grpc_error* error_ignored); static void incoming_byte_stream_publish_error( - grpc_chttp2_incoming_byte_stream* bs, grpc_error* error); -static void incoming_byte_stream_unref(grpc_chttp2_incoming_byte_stream* bs); - -static void benign_reclaimer_locked(void* t, grpc_error* error); -static void destructive_reclaimer_locked(void* t, grpc_error* error); - -static void post_benign_reclaimer(grpc_chttp2_transport* t); -static void post_destructive_reclaimer(grpc_chttp2_transport* t); - -static void close_transport_locked(grpc_chttp2_transport* t, grpc_error* error); -static void end_all_the_calls(grpc_chttp2_transport* t, grpc_error* error); - -static void schedule_bdp_ping_locked(grpc_chttp2_transport* t); -static void start_bdp_ping_locked(void* tp, grpc_error* error); -static void finish_bdp_ping_locked(void* tp, grpc_error* error); -static void next_bdp_ping_timer_expired_locked(void* tp, grpc_error* error); - -static void cancel_pings(grpc_chttp2_transport* t, grpc_error* error); -static void send_ping_locked(grpc_chttp2_transport* t, + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_byte_stream* bs, + grpc_error* error); +static void incoming_byte_stream_unref(grpc_exec_ctx* exec_ctx, + grpc_chttp2_incoming_byte_stream* bs); + +static void benign_reclaimer_locked(grpc_exec_ctx* exec_ctx, void* t, + grpc_error* error); +static void destructive_reclaimer_locked(grpc_exec_ctx* exec_ctx, void* t, + grpc_error* error); + +static void post_benign_reclaimer(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); +static void post_destructive_reclaimer(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); + +static void close_transport_locked(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_error* error); +static void end_all_the_calls(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_error* error); + +static void schedule_bdp_ping_locked(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); +static void start_bdp_ping_locked(grpc_exec_ctx* exec_ctx, void* tp, + grpc_error* error); +static void finish_bdp_ping_locked(grpc_exec_ctx* exec_ctx, void* tp, + grpc_error* error); +static void next_bdp_ping_timer_expired_locked(grpc_exec_ctx* exec_ctx, + void* tp, grpc_error* error); + +static void cancel_pings(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_error* error); +static void send_ping_locked(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_closure* on_initiate, grpc_closure* on_complete); -static void retry_initiate_ping_locked(void* tp, grpc_error* error); +static void retry_initiate_ping_locked(grpc_exec_ctx* exec_ctx, void* tp, + grpc_error* error); /** keepalive-relevant functions */ -static void init_keepalive_ping_locked(void* arg, grpc_error* error); -static void start_keepalive_ping_locked(void* arg, grpc_error* error); -static void finish_keepalive_ping_locked(void* arg, grpc_error* error); -static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error); - -static void reset_byte_stream(void* arg, grpc_error* error); +static void init_keepalive_ping_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error); +static void start_keepalive_ping_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error); +static void finish_keepalive_ping_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error); +static void keepalive_watchdog_fired_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error); + +static void reset_byte_stream(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error); /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING */ -static void destruct_transport(grpc_chttp2_transport* t) { +static void destruct_transport(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { size_t i; - grpc_endpoint_destroy(t->ep); + grpc_endpoint_destroy(exec_ctx, t->ep); - grpc_slice_buffer_destroy_internal(&t->qbuf); + grpc_slice_buffer_destroy_internal(exec_ctx, &t->qbuf); - grpc_slice_buffer_destroy_internal(&t->outbuf); - grpc_chttp2_hpack_compressor_destroy(&t->hpack_compressor); + grpc_slice_buffer_destroy_internal(exec_ctx, &t->outbuf); + grpc_chttp2_hpack_compressor_destroy(exec_ctx, &t->hpack_compressor); - grpc_slice_buffer_destroy_internal(&t->read_buffer); - grpc_chttp2_hpack_parser_destroy(&t->hpack_parser); + grpc_slice_buffer_destroy_internal(exec_ctx, &t->read_buffer); + grpc_chttp2_hpack_parser_destroy(exec_ctx, &t->hpack_parser); grpc_chttp2_goaway_parser_destroy(&t->goaway_parser); for (i = 0; i < STREAM_LIST_COUNT; i++) { @@ -178,11 +206,12 @@ static void destruct_transport(grpc_chttp2_transport* t) { GPR_ASSERT(grpc_chttp2_stream_map_size(&t->stream_map) == 0); grpc_chttp2_stream_map_destroy(&t->stream_map); - grpc_connectivity_state_destroy(&t->channel_callback.state_tracker); + grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker); - GRPC_COMBINER_UNREF(t->combiner, "chttp2_transport"); + GRPC_COMBINER_UNREF(exec_ctx, t->combiner, "chttp2_transport"); - cancel_pings(t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed")); + cancel_pings(exec_ctx, t, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed")); while (t->write_cb_pool) { grpc_chttp2_write_cb* next = t->write_cb_pool->next; @@ -199,7 +228,8 @@ static void destruct_transport(grpc_chttp2_transport* t) { } #ifndef NDEBUG -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason, +void grpc_chttp2_unref_transport(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, const char* reason, const char* file, int line) { if (grpc_trace_chttp2_refcount.enabled()) { gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count); @@ -207,7 +237,7 @@ void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason, t, val, val - 1, reason, file, line); } if (!gpr_unref(&t->refs)) return; - destruct_transport(t); + destruct_transport(exec_ctx, t); } void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason, @@ -220,9 +250,10 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason, gpr_ref(&t->refs); } #else -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t) { +void grpc_chttp2_unref_transport(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { if (!gpr_unref(&t->refs)) return; - destruct_transport(t); + destruct_transport(exec_ctx, t); } void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) { gpr_ref(&t->refs); } @@ -230,7 +261,7 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) { gpr_ref(&t->refs); } static const grpc_transport_vtable* get_vtable(void); -static void init_transport(grpc_chttp2_transport* t, +static void init_transport(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client) { size_t i; @@ -289,7 +320,7 @@ static void init_transport(grpc_chttp2_transport* t, t->goaway_error = GRPC_ERROR_NONE; grpc_chttp2_goaway_parser_init(&t->goaway_parser); - grpc_chttp2_hpack_parser_init(&t->hpack_parser); + grpc_chttp2_hpack_parser_init(exec_ctx, &t->hpack_parser); grpc_slice_buffer_init(&t->read_buffer); @@ -320,13 +351,14 @@ static void init_transport(grpc_chttp2_transport* t, /* configure http2 the way we like it */ if (is_client) { - queue_setting_update(t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0); - queue_setting_update(t, GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0); + queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_ENABLE_PUSH, 0); + queue_setting_update(exec_ctx, t, + GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0); } - queue_setting_update(t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, + queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, DEFAULT_MAX_HEADER_LIST_SIZE); - queue_setting_update(t, GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, - 1); + queue_setting_update(exec_ctx, t, + GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, 1); t->ping_policy.max_pings_without_data = g_default_max_pings_without_data; t->ping_policy.min_sent_ping_interval_without_data = @@ -501,7 +533,7 @@ static void init_transport(grpc_chttp2_transport* t, int value = grpc_channel_arg_get_integer( &channel_args->args[i], settings_map[j].integer_options); if (value >= 0) { - queue_setting_update(t, settings_map[j].setting_id, + queue_setting_update(exec_ctx, t, settings_map[j].setting_id, (uint32_t)value); } } @@ -512,7 +544,7 @@ static void init_transport(grpc_chttp2_transport* t, } } - t->flow_control.Init(t, enable_bdp); + t->flow_control.Init(exec_ctx, t, enable_bdp); /* No pings allowed before receiving a header or data frame. */ t->ping_state.pings_before_data_required = 0; @@ -526,8 +558,8 @@ static void init_transport(grpc_chttp2_transport* t, if (t->keepalive_time != GRPC_MILLIS_INF_FUTURE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING; GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping"); - grpc_timer_init(&t->keepalive_ping_timer, - grpc_core::ExecCtx::Get()->Now() + t->keepalive_time, + grpc_timer_init(exec_ctx, &t->keepalive_ping_timer, + grpc_exec_ctx_now(exec_ctx) + t->keepalive_time, &t->init_keepalive_ping_locked); } else { /* Use GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED to indicate there are no @@ -537,37 +569,42 @@ static void init_transport(grpc_chttp2_transport* t, if (enable_bdp) { GRPC_CHTTP2_REF_TRANSPORT(t, "bdp_ping"); - schedule_bdp_ping_locked(t); + schedule_bdp_ping_locked(exec_ctx, t); - grpc_chttp2_act_on_flowctl_action(t->flow_control->PeriodicUpdate(), t, - nullptr); + grpc_chttp2_act_on_flowctl_action( + exec_ctx, t->flow_control->PeriodicUpdate(exec_ctx), t, nullptr); } - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_INITIAL_WRITE); - post_benign_reclaimer(t); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_INITIAL_WRITE); + post_benign_reclaimer(exec_ctx, t); } -static void destroy_transport_locked(void* tp, grpc_error* error) { +static void destroy_transport_locked(grpc_exec_ctx* exec_ctx, void* tp, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp; t->destroying = 1; close_transport_locked( - t, grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"), - GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state)); - GRPC_CHTTP2_UNREF_TRANSPORT(t, "destroy"); + exec_ctx, t, + grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"), + GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state)); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destroy"); } -static void destroy_transport(grpc_transport* gt) { +static void destroy_transport(grpc_exec_ctx* exec_ctx, grpc_transport* gt) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)gt; - GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(destroy_transport_locked, t, + GRPC_CLOSURE_SCHED(exec_ctx, + GRPC_CLOSURE_CREATE(destroy_transport_locked, t, grpc_combiner_scheduler(t->combiner)), GRPC_ERROR_NONE); } -static void close_transport_locked(grpc_chttp2_transport* t, +static void close_transport_locked(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_error* error) { - end_all_the_calls(t, GRPC_ERROR_REF(error)); - cancel_pings(t, GRPC_ERROR_REF(error)); + end_all_the_calls(exec_ctx, t, GRPC_ERROR_REF(error)); + cancel_pings(exec_ctx, t, GRPC_ERROR_REF(error)); if (t->closed_with_error == GRPC_ERROR_NONE) { if (!grpc_error_has_clear_grpc_status(error)) { error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, @@ -585,21 +622,21 @@ static void close_transport_locked(grpc_chttp2_transport* t, } GPR_ASSERT(error != GRPC_ERROR_NONE); t->closed_with_error = GRPC_ERROR_REF(error); - connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), - "close_transport"); + connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_REF(error), "close_transport"); if (t->ping_state.is_delayed_ping_timer_set) { - grpc_timer_cancel(&t->ping_state.delayed_ping_timer); + grpc_timer_cancel(exec_ctx, &t->ping_state.delayed_ping_timer); } if (t->have_next_bdp_ping_timer) { - grpc_timer_cancel(&t->next_bdp_ping_timer); + grpc_timer_cancel(exec_ctx, &t->next_bdp_ping_timer); } switch (t->keepalive_state) { case GRPC_CHTTP2_KEEPALIVE_STATE_WAITING: - grpc_timer_cancel(&t->keepalive_ping_timer); + grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer); break; case GRPC_CHTTP2_KEEPALIVE_STATE_PINGING: - grpc_timer_cancel(&t->keepalive_ping_timer); - grpc_timer_cancel(&t->keepalive_watchdog_timer); + grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer); + grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer); break; case GRPC_CHTTP2_KEEPALIVE_STATE_DYING: case GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED: @@ -610,13 +647,14 @@ static void close_transport_locked(grpc_chttp2_transport* t, /* flush writable stream list to avoid dangling references */ grpc_chttp2_stream* s; while (grpc_chttp2_list_pop_writable_stream(t, &s)) { - GRPC_CHTTP2_STREAM_UNREF(s, "chttp2_writing:close"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:close"); } GPR_ASSERT(t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE); - grpc_endpoint_shutdown(t->ep, GRPC_ERROR_REF(error)); + grpc_endpoint_shutdown(exec_ctx, t->ep, GRPC_ERROR_REF(error)); } if (t->notify_on_receive_settings != nullptr) { - GRPC_CLOSURE_SCHED(t->notify_on_receive_settings, GRPC_ERROR_CANCELLED); + GRPC_CLOSURE_SCHED(exec_ctx, t->notify_on_receive_settings, + GRPC_ERROR_CANCELLED); t->notify_on_receive_settings = nullptr; } GRPC_ERROR_UNREF(error); @@ -626,21 +664,22 @@ static void close_transport_locked(grpc_chttp2_transport* t, void grpc_chttp2_stream_ref(grpc_chttp2_stream* s, const char* reason) { grpc_stream_ref(s->refcount, reason); } -void grpc_chttp2_stream_unref(grpc_chttp2_stream* s, const char* reason) { - grpc_stream_unref(s->refcount, reason); +void grpc_chttp2_stream_unref(grpc_exec_ctx* exec_ctx, grpc_chttp2_stream* s, + const char* reason) { + grpc_stream_unref(exec_ctx, s->refcount, reason); } #else void grpc_chttp2_stream_ref(grpc_chttp2_stream* s) { grpc_stream_ref(s->refcount); } -void grpc_chttp2_stream_unref(grpc_chttp2_stream* s) { - grpc_stream_unref(s->refcount); +void grpc_chttp2_stream_unref(grpc_exec_ctx* exec_ctx, grpc_chttp2_stream* s) { + grpc_stream_unref(exec_ctx, s->refcount); } #endif -static int init_stream(grpc_transport* gt, grpc_stream* gs, - grpc_stream_refcount* refcount, const void* server_data, - gpr_arena* arena) { +static int init_stream(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_stream_refcount* refcount, + const void* server_data, gpr_arena* arena) { GPR_TIMER_BEGIN("init_stream", 0); grpc_chttp2_transport* t = (grpc_chttp2_transport*)gt; grpc_chttp2_stream* s = (grpc_chttp2_stream*)gs; @@ -674,7 +713,7 @@ static int init_stream(grpc_transport* gt, grpc_stream* gs, s->id = (uint32_t)(uintptr_t)server_data; *t->accepting_stream = s; grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); - post_destructive_reclaimer(t); + post_destructive_reclaimer(exec_ctx, t); } s->flow_control.Init(t->flow_control.get(), s); @@ -683,7 +722,8 @@ static int init_stream(grpc_transport* gt, grpc_stream* gs, return 0; } -static void destroy_stream_locked(void* sp, grpc_error* error) { +static void destroy_stream_locked(grpc_exec_ctx* exec_ctx, void* sp, + grpc_error* error) { grpc_chttp2_stream* s = (grpc_chttp2_stream*)sp; grpc_chttp2_transport* t = s->t; @@ -694,10 +734,11 @@ static void destroy_stream_locked(void* sp, grpc_error* error) { GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == nullptr); } - grpc_slice_buffer_destroy_internal(&s->unprocessed_incoming_frames_buffer); - grpc_slice_buffer_destroy_internal(&s->frame_storage); - grpc_slice_buffer_destroy_internal(&s->compressed_data_buffer); - grpc_slice_buffer_destroy_internal(&s->decompressed_data_buffer); + grpc_slice_buffer_destroy_internal(exec_ctx, + &s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_destroy_internal(exec_ctx, &s->frame_storage); + grpc_slice_buffer_destroy_internal(exec_ctx, &s->compressed_data_buffer); + grpc_slice_buffer_destroy_internal(exec_ctx, &s->decompressed_data_buffer); grpc_chttp2_list_remove_stalled_by_transport(t, s); grpc_chttp2_list_remove_stalled_by_stream(t, s); @@ -716,24 +757,27 @@ static void destroy_stream_locked(void* sp, grpc_error* error) { GPR_ASSERT(s->recv_initial_metadata_ready == nullptr); GPR_ASSERT(s->recv_message_ready == nullptr); GPR_ASSERT(s->recv_trailing_metadata_finished == nullptr); - grpc_chttp2_data_parser_destroy(&s->data_parser); - grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[0]); - grpc_chttp2_incoming_metadata_buffer_destroy(&s->metadata_buffer[1]); - grpc_slice_buffer_destroy_internal(&s->flow_controlled_buffer); + grpc_chttp2_data_parser_destroy(exec_ctx, &s->data_parser); + grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx, + &s->metadata_buffer[0]); + grpc_chttp2_incoming_metadata_buffer_destroy(exec_ctx, + &s->metadata_buffer[1]); + grpc_slice_buffer_destroy_internal(exec_ctx, &s->flow_controlled_buffer); GRPC_ERROR_UNREF(s->read_closed_error); GRPC_ERROR_UNREF(s->write_closed_error); GRPC_ERROR_UNREF(s->byte_stream_error); s->flow_control.Destroy(); - GRPC_CHTTP2_UNREF_TRANSPORT(t, "stream"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "stream"); GPR_TIMER_END("destroy_stream", 0); - GRPC_CLOSURE_SCHED(s->destroy_stream_arg, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(exec_ctx, s->destroy_stream_arg, GRPC_ERROR_NONE); } -static void destroy_stream(grpc_transport* gt, grpc_stream* gs, +static void destroy_stream(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_closure* then_schedule_closure) { GPR_TIMER_BEGIN("destroy_stream", 0); grpc_chttp2_transport* t = (grpc_chttp2_transport*)gt; @@ -750,6 +794,7 @@ static void destroy_stream(grpc_transport* gt, grpc_stream* gs, s->destroy_stream_arg = then_schedule_closure; GRPC_CLOSURE_SCHED( + exec_ctx, GRPC_CLOSURE_INIT(&s->destroy_stream, destroy_stream_locked, s, grpc_combiner_scheduler(t->combiner)), GRPC_ERROR_NONE); @@ -761,7 +806,8 @@ grpc_chttp2_stream* grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport* t, return (grpc_chttp2_stream*)grpc_chttp2_stream_map_find(&t->stream_map, id); } -grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t, +grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, uint32_t id) { if (t->channel_callback.accept_stream == nullptr) { return nullptr; @@ -769,7 +815,8 @@ grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* accepting; GPR_ASSERT(t->accepting_stream == nullptr); t->accepting_stream = &accepting; - t->channel_callback.accept_stream(t->channel_callback.accept_stream_user_data, + t->channel_callback.accept_stream(exec_ctx, + t->channel_callback.accept_stream_user_data, &t->base, (void*)(uintptr_t)id); t->accepting_stream = nullptr; return accepting; @@ -791,7 +838,7 @@ static const char* write_state_name(grpc_chttp2_write_state st) { GPR_UNREACHABLE_CODE(return "UNKNOWN"); } -static void set_write_state(grpc_chttp2_transport* t, +static void set_write_state(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_chttp2_write_state st, const char* reason) { GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "W:%p %s state %s -> %s [%s]", t, t->is_client ? "CLIENT" : "SERVER", @@ -799,100 +846,108 @@ static void set_write_state(grpc_chttp2_transport* t, write_state_name(st), reason)); t->write_state = st; if (st == GRPC_CHTTP2_WRITE_STATE_IDLE) { - GRPC_CLOSURE_LIST_SCHED(&t->run_after_write); + GRPC_CLOSURE_LIST_SCHED(exec_ctx, &t->run_after_write); if (t->close_transport_on_writes_finished != nullptr) { grpc_error* err = t->close_transport_on_writes_finished; t->close_transport_on_writes_finished = nullptr; - close_transport_locked(t, err); + close_transport_locked(exec_ctx, t, err); } } } static void inc_initiate_write_reason( - grpc_chttp2_initiate_write_reason reason) { + grpc_exec_ctx* exec_ctx, grpc_chttp2_initiate_write_reason reason) { switch (reason) { case GRPC_CHTTP2_INITIATE_WRITE_INITIAL_WRITE: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_INITIAL_WRITE(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_INITIAL_WRITE(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_START_NEW_STREAM: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_START_NEW_STREAM(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_START_NEW_STREAM(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_SEND_MESSAGE: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_MESSAGE(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_MESSAGE(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_SEND_INITIAL_METADATA: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_INITIAL_METADATA(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_INITIAL_METADATA( + exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_SEND_TRAILING_METADATA: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_TRAILING_METADATA(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_TRAILING_METADATA( + exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_RETRY_SEND_PING: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_RETRY_SEND_PING(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_RETRY_SEND_PING(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_CONTINUE_PINGS: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_CONTINUE_PINGS(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_CONTINUE_PINGS(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_GOAWAY_SENT: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_GOAWAY_SENT(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_GOAWAY_SENT(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_RST_STREAM(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_RST_STREAM(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_CLOSE_FROM_API: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_CLOSE_FROM_API(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_CLOSE_FROM_API(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_STREAM_FLOW_CONTROL: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_STREAM_FLOW_CONTROL(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_STREAM_FLOW_CONTROL(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_TRANSPORT_FLOW_CONTROL: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_TRANSPORT_FLOW_CONTROL(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_TRANSPORT_FLOW_CONTROL( + exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_SEND_SETTINGS: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_SETTINGS(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_SETTINGS(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_FLOW_CONTROL_UNSTALLED_BY_SETTING: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_FLOW_CONTROL_UNSTALLED_BY_SETTING(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_FLOW_CONTROL_UNSTALLED_BY_SETTING( + exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_FLOW_CONTROL_UNSTALLED_BY_UPDATE: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_FLOW_CONTROL_UNSTALLED_BY_UPDATE(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_FLOW_CONTROL_UNSTALLED_BY_UPDATE( + exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_APPLICATION_PING: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_APPLICATION_PING(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_APPLICATION_PING(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_KEEPALIVE_PING: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_KEEPALIVE_PING(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_KEEPALIVE_PING(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_TRANSPORT_FLOW_CONTROL_UNSTALLED: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_TRANSPORT_FLOW_CONTROL_UNSTALLED(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_TRANSPORT_FLOW_CONTROL_UNSTALLED( + exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_PING_RESPONSE: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_PING_RESPONSE(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_PING_RESPONSE(exec_ctx); break; case GRPC_CHTTP2_INITIATE_WRITE_FORCE_RST_STREAM: - GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_FORCE_RST_STREAM(); + GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_FORCE_RST_STREAM(exec_ctx); break; } } -void grpc_chttp2_initiate_write(grpc_chttp2_transport* t, +void grpc_chttp2_initiate_write(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_initiate_write_reason reason) { GPR_TIMER_BEGIN("grpc_chttp2_initiate_write", 0); switch (t->write_state) { case GRPC_CHTTP2_WRITE_STATE_IDLE: - inc_initiate_write_reason(reason); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, + inc_initiate_write_reason(exec_ctx, reason); + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING, grpc_chttp2_initiate_write_reason_string(reason)); t->is_first_write_in_batch = true; GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); GRPC_CLOSURE_SCHED( + exec_ctx, GRPC_CLOSURE_INIT(&t->write_action_begin_locked, write_action_begin_locked, t, grpc_combiner_finally_scheduler(t->combiner)), GRPC_ERROR_NONE); break; case GRPC_CHTTP2_WRITE_STATE_WRITING: - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE, + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE, grpc_chttp2_initiate_write_reason_string(reason)); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: @@ -901,7 +956,8 @@ void grpc_chttp2_initiate_write(grpc_chttp2_transport* t, GPR_TIMER_END("grpc_chttp2_initiate_write", 0); } -void grpc_chttp2_mark_stream_writable(grpc_chttp2_transport* t, +void grpc_chttp2_mark_stream_writable(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s) { if (t->closed_with_error == GRPC_ERROR_NONE && grpc_chttp2_list_add_writable_stream(t, s)) { @@ -951,7 +1007,8 @@ static const char* begin_writing_desc(bool partial, bool inlined) { GPR_UNREACHABLE_CODE(return "bad state tuple"); } -static void write_action_begin_locked(void* gt, grpc_error* error_ignored) { +static void write_action_begin_locked(grpc_exec_ctx* exec_ctx, void* gt, + grpc_error* error_ignored) { GPR_TIMER_BEGIN("write_action_begin_locked", 0); grpc_chttp2_transport* t = (grpc_chttp2_transport*)gt; GPR_ASSERT(t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE); @@ -959,59 +1016,62 @@ static void write_action_begin_locked(void* gt, grpc_error* error_ignored) { if (t->closed_with_error != GRPC_ERROR_NONE) { r.writing = false; } else { - r = grpc_chttp2_begin_write(t); + r = grpc_chttp2_begin_write(exec_ctx, t); } if (r.writing) { if (r.partial) { - GRPC_STATS_INC_HTTP2_PARTIAL_WRITES(); + GRPC_STATS_INC_HTTP2_PARTIAL_WRITES(exec_ctx); } if (!t->is_first_write_in_batch) { - GRPC_STATS_INC_HTTP2_WRITES_CONTINUED(); + GRPC_STATS_INC_HTTP2_WRITES_CONTINUED(exec_ctx); } grpc_closure_scheduler* scheduler = write_scheduler(t, r.early_results_scheduled, r.partial); if (scheduler != grpc_schedule_on_exec_ctx) { - GRPC_STATS_INC_HTTP2_WRITES_OFFLOADED(); + GRPC_STATS_INC_HTTP2_WRITES_OFFLOADED(exec_ctx); } set_write_state( - t, + exec_ctx, t, r.partial ? GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE : GRPC_CHTTP2_WRITE_STATE_WRITING, begin_writing_desc(r.partial, scheduler == grpc_schedule_on_exec_ctx)); GRPC_CLOSURE_SCHED( + exec_ctx, GRPC_CLOSURE_INIT(&t->write_action, write_action, t, scheduler), GRPC_ERROR_NONE); } else { - GRPC_STATS_INC_HTTP2_SPURIOUS_WRITES_BEGUN(); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE, "begin writing nothing"); - GRPC_CHTTP2_UNREF_TRANSPORT(t, "writing"); + GRPC_STATS_INC_HTTP2_SPURIOUS_WRITES_BEGUN(exec_ctx); + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_IDLE, + "begin writing nothing"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); } GPR_TIMER_END("write_action_begin_locked", 0); } -static void write_action(void* gt, grpc_error* error) { +static void write_action(grpc_exec_ctx* exec_ctx, void* gt, grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)gt; GPR_TIMER_BEGIN("write_action", 0); grpc_endpoint_write( - t->ep, &t->outbuf, + exec_ctx, t->ep, &t->outbuf, GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t, grpc_combiner_scheduler(t->combiner))); GPR_TIMER_END("write_action", 0); } -static void write_action_end_locked(void* tp, grpc_error* error) { +static void write_action_end_locked(grpc_exec_ctx* exec_ctx, void* tp, + grpc_error* error) { GPR_TIMER_BEGIN("terminate_writing_with_lock", 0); grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp; if (error != GRPC_ERROR_NONE) { - close_transport_locked(t, GRPC_ERROR_REF(error)); + close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error)); } if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED) { t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SENT; if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { close_transport_locked( - t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("goaway sent")); + exec_ctx, t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("goaway sent")); } } @@ -1020,14 +1080,17 @@ static void write_action_end_locked(void* tp, grpc_error* error) { GPR_UNREACHABLE_CODE(break); case GRPC_CHTTP2_WRITE_STATE_WRITING: GPR_TIMER_MARK("state=writing", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_IDLE, "finish writing"); + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_IDLE, + "finish writing"); break; case GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE: GPR_TIMER_MARK("state=writing_stale_no_poller", 0); - set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, "continue writing"); + set_write_state(exec_ctx, t, GRPC_CHTTP2_WRITE_STATE_WRITING, + "continue writing"); t->is_first_write_in_batch = false; GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); GRPC_CLOSURE_RUN( + exec_ctx, GRPC_CLOSURE_INIT(&t->write_action_begin_locked, write_action_begin_locked, t, grpc_combiner_finally_scheduler(t->combiner)), @@ -1035,15 +1098,16 @@ static void write_action_end_locked(void* tp, grpc_error* error) { break; } - grpc_chttp2_end_write(t, GRPC_ERROR_REF(error)); + grpc_chttp2_end_write(exec_ctx, t, GRPC_ERROR_REF(error)); - GRPC_CHTTP2_UNREF_TRANSPORT(t, "writing"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing"); GPR_TIMER_END("terminate_writing_with_lock", 0); } // Dirties an HTTP2 setting to be sent out next time a writing path occurs. // If the change needs to occur immediately, manually initiate a write. -static void queue_setting_update(grpc_chttp2_transport* t, +static void queue_setting_update(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_setting_id id, uint32_t value) { const grpc_chttp2_setting_parameters* sp = &grpc_chttp2_settings_parameters[id]; @@ -1058,7 +1122,8 @@ static void queue_setting_update(grpc_chttp2_transport* t, } } -void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, +void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, uint32_t goaway_error, grpc_slice goaway_text) { // GRPC_CHTTP2_IF_TRACING( @@ -1093,11 +1158,12 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, /* lie: use transient failure from the transport to indicate goaway has been * received */ - connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, + connectivity_state_set(exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(t->goaway_error), "got_goaway"); } -static void maybe_start_some_streams(grpc_chttp2_transport* t) { +static void maybe_start_some_streams(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { grpc_chttp2_stream* s; /* start streams where we have free grpc_chttp2_stream ids and free * concurrency */ @@ -1117,21 +1183,22 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t) { if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) { connectivity_state_set( - t, GRPC_CHANNEL_TRANSIENT_FAILURE, + exec_ctx, t, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"), "no_more_stream_ids"); } grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); - post_destructive_reclaimer(t); - grpc_chttp2_mark_stream_writable(t, s); - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_START_NEW_STREAM); + post_destructive_reclaimer(exec_ctx, t); + grpc_chttp2_mark_stream_writable(exec_ctx, t, s); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_START_NEW_STREAM); } /* cancel out streams that will never be started */ while (t->next_stream_id >= MAX_CLIENT_STREAM_ID && grpc_chttp2_list_pop_waiting_for_concurrency(t, &s)) { grpc_chttp2_cancel_stream( - t, s, + exec_ctx, t, s, grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); @@ -1153,13 +1220,15 @@ static grpc_closure* add_closure_barrier(grpc_closure* closure) { return closure; } -static void null_then_run_closure(grpc_closure** closure, grpc_error* error) { +static void null_then_run_closure(grpc_exec_ctx* exec_ctx, + grpc_closure** closure, grpc_error* error) { grpc_closure* c = *closure; *closure = nullptr; - GRPC_CLOSURE_RUN(c, error); + GRPC_CLOSURE_RUN(exec_ctx, c, error); } -void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, +void grpc_chttp2_complete_closure_step(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_closure** pclosure, grpc_error* error, const char* desc) { @@ -1199,7 +1268,7 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, } if ((t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE) || !(closure->next_data.scratch & CLOSURE_BARRIER_MAY_COVER_WRITE)) { - GRPC_CLOSURE_RUN(closure, closure->error_data.error); + GRPC_CLOSURE_RUN(exec_ctx, closure, closure->error_data.error); } else { grpc_closure_list_append(&t->run_after_write, closure, closure->error_data.error); @@ -1215,24 +1284,28 @@ static bool contains_non_ok_status(grpc_metadata_batch* batch) { return false; } -static void maybe_become_writable_due_to_send_msg(grpc_chttp2_transport* t, +static void maybe_become_writable_due_to_send_msg(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s) { if (s->id != 0 && (!s->write_buffering || s->flow_controlled_buffer.length > t->write_buffer_size)) { - grpc_chttp2_mark_stream_writable(t, s); - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_SEND_MESSAGE); + grpc_chttp2_mark_stream_writable(exec_ctx, t, s); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_SEND_MESSAGE); } } -static void add_fetched_slice_locked(grpc_chttp2_transport* t, +static void add_fetched_slice_locked(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s) { s->fetched_send_message_length += (uint32_t)GRPC_SLICE_LENGTH(s->fetching_slice); grpc_slice_buffer_add(&s->flow_controlled_buffer, s->fetching_slice); - maybe_become_writable_due_to_send_msg(t, s); + maybe_become_writable_due_to_send_msg(exec_ctx, t, s); } -static void continue_fetching_send_locked(grpc_chttp2_transport* t, +static void continue_fetching_send_locked(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s) { for (;;) { if (s->fetching_send_message == nullptr) { @@ -1241,11 +1314,11 @@ static void continue_fetching_send_locked(grpc_chttp2_transport* t, return; /* early out */ } if (s->fetched_send_message_length == s->fetching_send_message->length) { - grpc_byte_stream_destroy(s->fetching_send_message); + grpc_byte_stream_destroy(exec_ctx, s->fetching_send_message); int64_t notify_offset = s->next_message_end_offset; if (notify_offset <= s->flow_controlled_bytes_written) { grpc_chttp2_complete_closure_step( - t, s, &s->fetching_send_message_finished, GRPC_ERROR_NONE, + exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_NONE, "fetching_send_message_finished"); } else { grpc_chttp2_write_cb* cb = t->write_cb_pool; @@ -1266,37 +1339,39 @@ static void continue_fetching_send_locked(grpc_chttp2_transport* t, } s->fetching_send_message = nullptr; return; /* early out */ - } else if (grpc_byte_stream_next(s->fetching_send_message, UINT32_MAX, - &s->complete_fetch_locked)) { - grpc_error* error = - grpc_byte_stream_pull(s->fetching_send_message, &s->fetching_slice); + } else if (grpc_byte_stream_next(exec_ctx, s->fetching_send_message, + UINT32_MAX, &s->complete_fetch_locked)) { + grpc_error* error = grpc_byte_stream_pull( + exec_ctx, s->fetching_send_message, &s->fetching_slice); if (error != GRPC_ERROR_NONE) { - grpc_byte_stream_destroy(s->fetching_send_message); - grpc_chttp2_cancel_stream(t, s, error); + grpc_byte_stream_destroy(exec_ctx, s->fetching_send_message); + grpc_chttp2_cancel_stream(exec_ctx, t, s, error); } else { - add_fetched_slice_locked(t, s); + add_fetched_slice_locked(exec_ctx, t, s); } } } } -static void complete_fetch_locked(void* gs, grpc_error* error) { +static void complete_fetch_locked(grpc_exec_ctx* exec_ctx, void* gs, + grpc_error* error) { grpc_chttp2_stream* s = (grpc_chttp2_stream*)gs; grpc_chttp2_transport* t = s->t; if (error == GRPC_ERROR_NONE) { - error = grpc_byte_stream_pull(s->fetching_send_message, &s->fetching_slice); + error = grpc_byte_stream_pull(exec_ctx, s->fetching_send_message, + &s->fetching_slice); if (error == GRPC_ERROR_NONE) { - add_fetched_slice_locked(t, s); - continue_fetching_send_locked(t, s); + add_fetched_slice_locked(exec_ctx, t, s); + continue_fetching_send_locked(exec_ctx, t, s); } } if (error != GRPC_ERROR_NONE) { - grpc_byte_stream_destroy(s->fetching_send_message); - grpc_chttp2_cancel_stream(t, s, error); + grpc_byte_stream_destroy(exec_ctx, s->fetching_send_message); + grpc_chttp2_cancel_stream(exec_ctx, t, s, error); } } -static void do_nothing(void* arg, grpc_error* error) {} +static void do_nothing(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {} static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, bool is_client, bool is_initial) { @@ -1311,7 +1386,7 @@ static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, } } -static void perform_stream_op_locked(void* stream_op, +static void perform_stream_op_locked(grpc_exec_ctx* exec_ctx, void* stream_op, grpc_error* error_ignored) { GPR_TIMER_BEGIN("perform_stream_op_locked", 0); @@ -1321,7 +1396,7 @@ static void perform_stream_op_locked(void* stream_op, grpc_transport_stream_op_batch_payload* op_payload = op->payload; grpc_chttp2_transport* t = s->t; - GRPC_STATS_INC_HTTP2_OP_BATCHES(); + GRPC_STATS_INC_HTTP2_OP_BATCHES(exec_ctx); if (grpc_http_trace.enabled()) { char* str = grpc_transport_stream_op_batch_string(op); @@ -1356,12 +1431,13 @@ static void perform_stream_op_locked(void* stream_op, } if (op->cancel_stream) { - GRPC_STATS_INC_HTTP2_OP_CANCEL(); - grpc_chttp2_cancel_stream(t, s, op_payload->cancel_stream.cancel_error); + GRPC_STATS_INC_HTTP2_OP_CANCEL(exec_ctx); + grpc_chttp2_cancel_stream(exec_ctx, t, s, + op_payload->cancel_stream.cancel_error); } if (op->send_initial_metadata) { - GRPC_STATS_INC_HTTP2_OP_SEND_INITIAL_METADATA(); + GRPC_STATS_INC_HTTP2_OP_SEND_INITIAL_METADATA(exec_ctx); GPR_ASSERT(s->send_initial_metadata_finished == nullptr); on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE; @@ -1389,7 +1465,7 @@ static void perform_stream_op_locked(void* stream_op, } if (metadata_size > metadata_peer_limit) { grpc_chttp2_cancel_stream( - t, s, + exec_ctx, t, s, grpc_error_set_int( grpc_error_set_int( grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -1408,10 +1484,10 @@ static void perform_stream_op_locked(void* stream_op, 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); + maybe_start_some_streams(exec_ctx, t); } else { grpc_chttp2_cancel_stream( - t, s, + exec_ctx, t, s, grpc_error_set_int( GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Transport closed", &t->closed_with_error, 1), @@ -1419,18 +1495,18 @@ static void perform_stream_op_locked(void* stream_op, } } else { GPR_ASSERT(s->id != 0); - grpc_chttp2_mark_stream_writable(t, s); + grpc_chttp2_mark_stream_writable(exec_ctx, 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); + exec_ctx, 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, + exec_ctx, 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), @@ -1444,9 +1520,9 @@ static void perform_stream_op_locked(void* stream_op, } if (op->send_message) { - GRPC_STATS_INC_HTTP2_OP_SEND_MESSAGE(); + GRPC_STATS_INC_HTTP2_OP_SEND_MESSAGE(exec_ctx); GRPC_STATS_INC_HTTP2_SEND_MESSAGE_SIZE( - op->payload->send_message.send_message->length); + exec_ctx, op->payload->send_message.send_message->length); on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE; s->fetching_send_message_finished = add_closure_barrier(op->on_complete); if (s->write_closed) { @@ -1456,7 +1532,7 @@ static void perform_stream_op_locked(void* stream_op, // recv_message failure, breaking out of its loop, and then // starting recv_trailing_metadata. grpc_chttp2_complete_closure_step( - t, s, &s->fetching_send_message_finished, + exec_ctx, t, s, &s->fetching_send_message_finished, t->is_client && s->received_trailing_metadata ? GRPC_ERROR_NONE : GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -1485,13 +1561,13 @@ static void perform_stream_op_locked(void* stream_op, } else { s->write_buffering = false; } - continue_fetching_send_locked(t, s); - maybe_become_writable_due_to_send_msg(t, s); + continue_fetching_send_locked(exec_ctx, t, s); + maybe_become_writable_due_to_send_msg(exec_ctx, t, s); } } if (op->send_trailing_metadata) { - GRPC_STATS_INC_HTTP2_OP_SEND_TRAILING_METADATA(); + GRPC_STATS_INC_HTTP2_OP_SEND_TRAILING_METADATA(exec_ctx); GPR_ASSERT(s->send_trailing_metadata_finished == nullptr); on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE; s->send_trailing_metadata_finished = add_closure_barrier(on_complete); @@ -1505,7 +1581,7 @@ static void perform_stream_op_locked(void* stream_op, [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; if (metadata_size > metadata_peer_limit) { grpc_chttp2_cancel_stream( - t, s, + exec_ctx, t, s, grpc_error_set_int( grpc_error_set_int( grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -1522,7 +1598,7 @@ static void perform_stream_op_locked(void* stream_op, if (s->write_closed) { s->send_trailing_metadata = nullptr; grpc_chttp2_complete_closure_step( - t, s, &s->send_trailing_metadata_finished, + exec_ctx, t, s, &s->send_trailing_metadata_finished, grpc_metadata_batch_is_empty( op->payload->send_trailing_metadata.send_trailing_metadata) ? GRPC_ERROR_NONE @@ -1533,15 +1609,15 @@ static void perform_stream_op_locked(void* stream_op, } 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_mark_stream_writable(exec_ctx, t, s); grpc_chttp2_initiate_write( - t, GRPC_CHTTP2_INITIATE_WRITE_SEND_TRAILING_METADATA); + exec_ctx, t, GRPC_CHTTP2_INITIATE_WRITE_SEND_TRAILING_METADATA); } } } if (op->recv_initial_metadata) { - GRPC_STATS_INC_HTTP2_OP_RECV_INITIAL_METADATA(); + GRPC_STATS_INC_HTTP2_OP_RECV_INITIAL_METADATA(exec_ctx); GPR_ASSERT(s->recv_initial_metadata_ready == nullptr); s->recv_initial_metadata_ready = op_payload->recv_initial_metadata.recv_initial_metadata_ready; @@ -1553,11 +1629,11 @@ static void perform_stream_op_locked(void* stream_op, gpr_atm_rel_store(op_payload->recv_initial_metadata.peer_string, (gpr_atm)gpr_strdup(t->peer_string)); } - grpc_chttp2_maybe_complete_recv_initial_metadata(t, s); + grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s); } if (op->recv_message) { - GRPC_STATS_INC_HTTP2_OP_RECV_MESSAGE(); + GRPC_STATS_INC_HTTP2_OP_RECV_MESSAGE(exec_ctx); size_t already_received; GPR_ASSERT(s->recv_message_ready == nullptr); GPR_ASSERT(!s->pending_byte_stream); @@ -1568,30 +1644,32 @@ static void perform_stream_op_locked(void* stream_op, already_received = s->frame_storage.length; s->flow_control->IncomingByteStreamUpdate(GRPC_HEADER_SIZE_IN_BYTES, already_received); - grpc_chttp2_act_on_flowctl_action(s->flow_control->MakeAction(), t, s); + grpc_chttp2_act_on_flowctl_action(exec_ctx, + s->flow_control->MakeAction(), t, s); } } - grpc_chttp2_maybe_complete_recv_message(t, s); + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } if (op->recv_trailing_metadata) { - GRPC_STATS_INC_HTTP2_OP_RECV_TRAILING_METADATA(); + GRPC_STATS_INC_HTTP2_OP_RECV_TRAILING_METADATA(exec_ctx); GPR_ASSERT(s->recv_trailing_metadata_finished == nullptr); s->recv_trailing_metadata_finished = add_closure_barrier(on_complete); s->recv_trailing_metadata = op_payload->recv_trailing_metadata.recv_trailing_metadata; s->final_metadata_requested = true; - grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } - grpc_chttp2_complete_closure_step(t, s, &on_complete, GRPC_ERROR_NONE, - "op->on_complete"); + grpc_chttp2_complete_closure_step(exec_ctx, t, s, &on_complete, + GRPC_ERROR_NONE, "op->on_complete"); GPR_TIMER_END("perform_stream_op_locked", 0); - GRPC_CHTTP2_STREAM_UNREF(s, "perform_stream_op"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "perform_stream_op"); } -static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, +static void perform_stream_op(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_transport_stream_op_batch* op) { GPR_TIMER_BEGIN("perform_stream_op", 0); grpc_chttp2_transport* t = (grpc_chttp2_transport*)gt; @@ -1619,29 +1697,32 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, op->handler_private.extra_arg = gs; GRPC_CHTTP2_STREAM_REF(s, "perform_stream_op"); GRPC_CLOSURE_SCHED( + exec_ctx, GRPC_CLOSURE_INIT(&op->handler_private.closure, perform_stream_op_locked, op, grpc_combiner_scheduler(t->combiner)), GRPC_ERROR_NONE); GPR_TIMER_END("perform_stream_op", 0); } -static void cancel_pings(grpc_chttp2_transport* t, grpc_error* error) { +static void cancel_pings(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_error* error) { /* callback remaining pings: they're not allowed to call into the transpot, and maybe they hold resources that need to be freed */ grpc_chttp2_ping_queue* pq = &t->ping_queue; GPR_ASSERT(error != GRPC_ERROR_NONE); 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_SCHED(&pq->lists[j]); + GRPC_CLOSURE_LIST_SCHED(exec_ctx, &pq->lists[j]); } GRPC_ERROR_UNREF(error); } -static void send_ping_locked(grpc_chttp2_transport* t, +static void send_ping_locked(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_closure* on_initiate, grpc_closure* on_ack) { if (t->closed_with_error != GRPC_ERROR_NONE) { - GRPC_CLOSURE_SCHED(on_initiate, GRPC_ERROR_REF(t->closed_with_error)); - GRPC_CLOSURE_SCHED(on_ack, GRPC_ERROR_REF(t->closed_with_error)); + GRPC_CLOSURE_SCHED(exec_ctx, on_initiate, + GRPC_ERROR_REF(t->closed_with_error)); + GRPC_CLOSURE_SCHED(exec_ctx, on_ack, GRPC_ERROR_REF(t->closed_with_error)); return; } grpc_chttp2_ping_queue* pq = &t->ping_queue; @@ -1651,15 +1732,18 @@ static void send_ping_locked(grpc_chttp2_transport* t, GRPC_ERROR_NONE); } -static void retry_initiate_ping_locked(void* tp, grpc_error* error) { +static void retry_initiate_ping_locked(grpc_exec_ctx* exec_ctx, void* tp, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp; t->ping_state.is_delayed_ping_timer_set = false; if (error == GRPC_ERROR_NONE) { - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RETRY_SEND_PING); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_RETRY_SEND_PING); } } -void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id) { +void grpc_chttp2_ack_ping(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + uint64_t id) { grpc_chttp2_ping_queue* pq = &t->ping_queue; if (pq->inflight_id != id) { char* from = grpc_endpoint_get_peer(t->ep); @@ -1667,48 +1751,54 @@ void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id) { gpr_free(from); return; } - GRPC_CLOSURE_LIST_SCHED(&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]); + GRPC_CLOSURE_LIST_SCHED(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]); if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_NEXT])) { - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_CONTINUE_PINGS); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_CONTINUE_PINGS); } } -static void send_goaway(grpc_chttp2_transport* t, grpc_error* error) { +static void send_goaway(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_error* error) { t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED; grpc_http2_error_code http_error; grpc_slice slice; - grpc_error_get_status(error, GRPC_MILLIS_INF_FUTURE, nullptr, &slice, - &http_error, nullptr); + grpc_error_get_status(exec_ctx, error, GRPC_MILLIS_INF_FUTURE, nullptr, + &slice, &http_error, nullptr); grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error, grpc_slice_ref_internal(slice), &t->qbuf); - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_GOAWAY_SENT); + grpc_chttp2_initiate_write(exec_ctx, 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_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { t->ping_recv_state.ping_strikes++; if (++t->ping_recv_state.ping_strikes > t->ping_policy.max_ping_strikes && t->ping_policy.max_ping_strikes != 0) { - send_goaway(t, + send_goaway(exec_ctx, t, grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("too_many_pings"), GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM)); /*The transport will be closed after the write is done */ close_transport_locked( - t, grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many pings"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + exec_ctx, t, + grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many pings"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); } } -static void perform_transport_op_locked(void* stream_op, +static void perform_transport_op_locked(grpc_exec_ctx* exec_ctx, + void* stream_op, grpc_error* error_ignored) { grpc_transport_op* op = (grpc_transport_op*)stream_op; grpc_chttp2_transport* t = (grpc_chttp2_transport*)op->handler_private.extra_arg; if (op->goaway_error) { - send_goaway(t, op->goaway_error); + send_goaway(exec_ctx, t, op->goaway_error); } if (op->set_accept_stream) { @@ -1718,40 +1808,43 @@ static void perform_transport_op_locked(void* stream_op, } if (op->bind_pollset) { - grpc_endpoint_add_to_pollset(t->ep, op->bind_pollset); + grpc_endpoint_add_to_pollset(exec_ctx, t->ep, op->bind_pollset); } if (op->bind_pollset_set) { - grpc_endpoint_add_to_pollset_set(t->ep, op->bind_pollset_set); + grpc_endpoint_add_to_pollset_set(exec_ctx, t->ep, op->bind_pollset_set); } if (op->send_ping) { - send_ping_locked(t, nullptr, op->send_ping); - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_APPLICATION_PING); + send_ping_locked(exec_ctx, t, nullptr, op->send_ping); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_APPLICATION_PING); } if (op->on_connectivity_state_change != nullptr) { grpc_connectivity_state_notify_on_state_change( - &t->channel_callback.state_tracker, op->connectivity_state, + exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state, op->on_connectivity_state_change); } if (op->disconnect_with_error != GRPC_ERROR_NONE) { - close_transport_locked(t, op->disconnect_with_error); + close_transport_locked(exec_ctx, t, op->disconnect_with_error); } - GRPC_CLOSURE_RUN(op->on_consumed, GRPC_ERROR_NONE); + GRPC_CLOSURE_RUN(exec_ctx, op->on_consumed, GRPC_ERROR_NONE); - GRPC_CHTTP2_UNREF_TRANSPORT(t, "transport_op"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "transport_op"); } -static void perform_transport_op(grpc_transport* gt, grpc_transport_op* op) { +static void perform_transport_op(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_transport_op* op) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)gt; char* msg = grpc_transport_op_string(op); gpr_free(msg); op->handler_private.extra_arg = gt; GRPC_CHTTP2_REF_TRANSPORT(t, "transport_op"); - GRPC_CLOSURE_SCHED(GRPC_CLOSURE_INIT(&op->handler_private.closure, + GRPC_CLOSURE_SCHED(exec_ctx, + GRPC_CLOSURE_INIT(&op->handler_private.closure, perform_transport_op_locked, op, grpc_combiner_scheduler(t->combiner)), GRPC_ERROR_NONE); @@ -1761,33 +1854,36 @@ static void perform_transport_op(grpc_transport* gt, grpc_transport_op* op) { * INPUT PROCESSING - GENERAL */ -void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_chttp2_transport* t, +void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s) { if (s->recv_initial_metadata_ready != nullptr && s->published_metadata[0] != GRPC_METADATA_NOT_PUBLISHED) { if (s->seen_error) { - grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); if (!s->pending_byte_stream) { grpc_slice_buffer_reset_and_unref_internal( - &s->unprocessed_incoming_frames_buffer); + exec_ctx, &s->unprocessed_incoming_frames_buffer); } } - grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0], - s->recv_initial_metadata); - null_then_run_closure(&s->recv_initial_metadata_ready, GRPC_ERROR_NONE); + grpc_chttp2_incoming_metadata_buffer_publish( + exec_ctx, &s->metadata_buffer[0], s->recv_initial_metadata); + null_then_run_closure(exec_ctx, &s->recv_initial_metadata_ready, + GRPC_ERROR_NONE); } } -void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, +void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s) { grpc_error* error = GRPC_ERROR_NONE; if (s->recv_message_ready != nullptr) { *s->recv_message = nullptr; if (s->final_metadata_requested && s->seen_error) { - grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); if (!s->pending_byte_stream) { grpc_slice_buffer_reset_and_unref_internal( - &s->unprocessed_incoming_frames_buffer); + exec_ctx, &s->unprocessed_incoming_frames_buffer); } } if (!s->pending_byte_stream) { @@ -1814,9 +1910,10 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, &s->decompressed_data_buffer, nullptr, GRPC_HEADER_SIZE_IN_BYTES - s->decompressed_header_bytes, &end_of_context)) { - grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, + &s->frame_storage); grpc_slice_buffer_reset_and_unref_internal( - &s->unprocessed_incoming_frames_buffer); + exec_ctx, &s->unprocessed_incoming_frames_buffer); error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Stream decompression error."); } else { @@ -1825,8 +1922,8 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, s->decompressed_header_bytes = 0; } error = grpc_deframe_unprocessed_incoming_frames( - &s->data_parser, s, &s->decompressed_data_buffer, nullptr, - s->recv_message); + exec_ctx, &s->data_parser, s, &s->decompressed_data_buffer, + nullptr, s->recv_message); if (end_of_context) { grpc_stream_compression_context_destroy( s->stream_decompression_ctx); @@ -1835,14 +1932,15 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, } } else { error = grpc_deframe_unprocessed_incoming_frames( - &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, - nullptr, s->recv_message); + exec_ctx, &s->data_parser, s, + &s->unprocessed_incoming_frames_buffer, nullptr, s->recv_message); } if (error != GRPC_ERROR_NONE) { s->seen_error = true; - grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, + &s->frame_storage); grpc_slice_buffer_reset_and_unref_internal( - &s->unprocessed_incoming_frames_buffer); + exec_ctx, &s->unprocessed_incoming_frames_buffer); break; } else if (*s->recv_message != nullptr) { break; @@ -1850,25 +1948,26 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, } } if (error == GRPC_ERROR_NONE && *s->recv_message != nullptr) { - null_then_run_closure(&s->recv_message_ready, GRPC_ERROR_NONE); + null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { *s->recv_message = nullptr; - null_then_run_closure(&s->recv_message_ready, GRPC_ERROR_NONE); + null_then_run_closure(exec_ctx, &s->recv_message_ready, GRPC_ERROR_NONE); } GRPC_ERROR_UNREF(error); } } -void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t, +void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s) { - grpc_chttp2_maybe_complete_recv_message(t, s); + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); if (s->recv_trailing_metadata_finished != nullptr && s->read_closed && s->write_closed) { if (s->seen_error) { - grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); if (!s->pending_byte_stream) { grpc_slice_buffer_reset_and_unref_internal( - &s->unprocessed_incoming_frames_buffer); + exec_ctx, &s->unprocessed_incoming_frames_buffer); } } bool pending_data = s->pending_byte_stream || @@ -1886,9 +1985,9 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t, s->stream_decompression_ctx, &s->frame_storage, &s->unprocessed_incoming_frames_buffer, nullptr, GRPC_HEADER_SIZE_IN_BYTES, &end_of_context)) { - grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &s->frame_storage); grpc_slice_buffer_reset_and_unref_internal( - &s->unprocessed_incoming_frames_buffer); + exec_ctx, &s->unprocessed_incoming_frames_buffer); s->seen_error = true; } else { if (s->unprocessed_incoming_frames_buffer.length > 0) { @@ -1903,23 +2002,23 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t, } if (s->read_closed && s->frame_storage.length == 0 && !pending_data && s->recv_trailing_metadata_finished != nullptr) { - grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1], - s->recv_trailing_metadata); + grpc_chttp2_incoming_metadata_buffer_publish( + exec_ctx, &s->metadata_buffer[1], s->recv_trailing_metadata); grpc_chttp2_complete_closure_step( - t, s, &s->recv_trailing_metadata_finished, GRPC_ERROR_NONE, + exec_ctx, t, s, &s->recv_trailing_metadata_finished, GRPC_ERROR_NONE, "recv_trailing_metadata_finished"); } } } -static void remove_stream(grpc_chttp2_transport* t, uint32_t id, - grpc_error* error) { +static void remove_stream(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + uint32_t id, grpc_error* error) { grpc_chttp2_stream* s = (grpc_chttp2_stream*)grpc_chttp2_stream_map_delete(&t->stream_map, id); GPR_ASSERT(s); if (t->incoming_stream == s) { t->incoming_stream = nullptr; - grpc_chttp2_parsing_become_skip_parser(t); + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); } if (s->pending_byte_stream) { if (s->on_next != nullptr) { @@ -1927,8 +2026,8 @@ static void remove_stream(grpc_chttp2_transport* t, uint32_t id, if (error == GRPC_ERROR_NONE) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); } - incoming_byte_stream_publish_error(bs, error); - incoming_byte_stream_unref(bs); + incoming_byte_stream_publish_error(exec_ctx, bs, error); + incoming_byte_stream_unref(exec_ctx, bs); s->data_parser.parsing_frame = nullptr; } else { GRPC_ERROR_UNREF(s->byte_stream_error); @@ -1937,52 +2036,56 @@ static void remove_stream(grpc_chttp2_transport* t, uint32_t id, } if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { - post_benign_reclaimer(t); + post_benign_reclaimer(exec_ctx, t); if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SENT) { close_transport_locked( - t, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Last stream closed after sending GOAWAY", &error, 1)); + exec_ctx, t, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Last stream closed after sending GOAWAY", &error, 1)); } } if (grpc_chttp2_list_remove_writable_stream(t, s)) { - GRPC_CHTTP2_STREAM_UNREF(s, "chttp2_writing:remove_stream"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:remove_stream"); } GRPC_ERROR_UNREF(error); - maybe_start_some_streams(t); + maybe_start_some_streams(exec_ctx, t); } -void grpc_chttp2_cancel_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s, +void grpc_chttp2_cancel_stream(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_error* due_to_error) { if (!t->is_client && !s->sent_trailing_metadata && grpc_error_has_clear_grpc_status(due_to_error)) { - close_from_api(t, s, due_to_error); + close_from_api(exec_ctx, t, s, due_to_error); return; } if (!s->read_closed || !s->write_closed) { if (s->id != 0) { grpc_http2_error_code http_error; - grpc_error_get_status(due_to_error, s->deadline, nullptr, nullptr, - &http_error, nullptr); + grpc_error_get_status(exec_ctx, due_to_error, s->deadline, nullptr, + nullptr, &http_error, nullptr); grpc_slice_buffer_add( &t->qbuf, grpc_chttp2_rst_stream_create(s->id, (uint32_t)http_error, &s->stats.outgoing)); - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM); } } if (due_to_error != GRPC_ERROR_NONE && !s->seen_error) { s->seen_error = true; } - grpc_chttp2_mark_stream_closed(t, s, 1, 1, due_to_error); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, due_to_error); } -void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_error* error) { +void grpc_chttp2_fake_status(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_chttp2_stream* s, grpc_error* error) { grpc_status_code status; grpc_slice slice; - grpc_error_get_status(error, s->deadline, &status, &slice, nullptr, nullptr); + grpc_error_get_status(exec_ctx, error, s->deadline, &status, &slice, nullptr, + nullptr); if (status != GRPC_STATUS_OK) { s->seen_error = true; } @@ -1998,20 +2101,20 @@ void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* s, gpr_ltoa(status, status_string); GRPC_LOG_IF_ERROR("add_status", grpc_chttp2_incoming_metadata_buffer_replace_or_add( - &s->metadata_buffer[1], + exec_ctx, &s->metadata_buffer[1], grpc_mdelem_from_slices( - GRPC_MDSTR_GRPC_STATUS, + exec_ctx, GRPC_MDSTR_GRPC_STATUS, grpc_slice_from_copied_string(status_string)))); if (!GRPC_SLICE_IS_EMPTY(slice)) { GRPC_LOG_IF_ERROR( "add_status_message", grpc_chttp2_incoming_metadata_buffer_replace_or_add( - &s->metadata_buffer[1], - grpc_mdelem_from_slices(GRPC_MDSTR_GRPC_MESSAGE, + exec_ctx, &s->metadata_buffer[1], + grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, grpc_slice_ref_internal(slice)))); } 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(exec_ctx, t, s); } GRPC_ERROR_UNREF(error); @@ -2044,12 +2147,14 @@ static grpc_error* removal_error(grpc_error* extra_error, grpc_chttp2_stream* s, return error; } -static void flush_write_list(grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_chttp2_write_cb** list, grpc_error* error) { +static void flush_write_list(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_chttp2_stream* s, grpc_chttp2_write_cb** list, + grpc_error* error) { while (*list) { grpc_chttp2_write_cb* cb = *list; *list = cb->next; - grpc_chttp2_complete_closure_step(t, s, &cb->closure, GRPC_ERROR_REF(error), + grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, + GRPC_ERROR_REF(error), "on_write_finished_cb"); cb->next = t->write_cb_pool; t->write_cb_pool = cb; @@ -2057,34 +2162,37 @@ static void flush_write_list(grpc_chttp2_transport* t, grpc_chttp2_stream* s, GRPC_ERROR_UNREF(error); } -void grpc_chttp2_fail_pending_writes(grpc_chttp2_transport* t, +void grpc_chttp2_fail_pending_writes(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_error* error) { error = removal_error(error, s, "Pending writes failed due to stream closure"); s->send_initial_metadata = nullptr; - grpc_chttp2_complete_closure_step(t, s, &s->send_initial_metadata_finished, - GRPC_ERROR_REF(error), - "send_initial_metadata_finished"); + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->send_initial_metadata_finished, GRPC_ERROR_REF(error), + "send_initial_metadata_finished"); s->send_trailing_metadata = nullptr; - grpc_chttp2_complete_closure_step(t, s, &s->send_trailing_metadata_finished, - GRPC_ERROR_REF(error), - "send_trailing_metadata_finished"); + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->send_trailing_metadata_finished, + GRPC_ERROR_REF(error), "send_trailing_metadata_finished"); s->fetching_send_message = nullptr; - grpc_chttp2_complete_closure_step(t, s, &s->fetching_send_message_finished, - GRPC_ERROR_REF(error), - "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_flow_controlled_cbs, error); + grpc_chttp2_complete_closure_step( + exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_REF(error), + "fetching_send_message_finished"); + flush_write_list(exec_ctx, t, s, &s->on_write_finished_cbs, + GRPC_ERROR_REF(error)); + flush_write_list(exec_ctx, t, s, &s->on_flow_controlled_cbs, error); } -void grpc_chttp2_mark_stream_closed(grpc_chttp2_transport* t, +void grpc_chttp2_mark_stream_closed(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, int close_reads, int close_writes, grpc_error* error) { if (s->read_closed && s->write_closed) { /* already closed */ - grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); GRPC_ERROR_UNREF(error); return; } @@ -2098,20 +2206,20 @@ void grpc_chttp2_mark_stream_closed(grpc_chttp2_transport* t, if (close_writes && !s->write_closed) { s->write_closed_error = GRPC_ERROR_REF(error); s->write_closed = true; - grpc_chttp2_fail_pending_writes(t, s, GRPC_ERROR_REF(error)); + grpc_chttp2_fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error)); } if (s->read_closed && s->write_closed) { became_closed = true; grpc_error* overall_error = removal_error(GRPC_ERROR_REF(error), s, "Stream removed"); if (s->id != 0) { - remove_stream(t, s->id, GRPC_ERROR_REF(overall_error)); + remove_stream(exec_ctx, t, s->id, GRPC_ERROR_REF(overall_error)); } else { /* Purge streams waiting on concurrency still waiting for id assignment */ grpc_chttp2_list_remove_waiting_for_concurrency(t, s); } if (overall_error != GRPC_ERROR_NONE) { - grpc_chttp2_fake_status(t, s, overall_error); + grpc_chttp2_fake_status(exec_ctx, t, s, overall_error); } } if (closed_read) { @@ -2120,18 +2228,18 @@ void grpc_chttp2_mark_stream_closed(grpc_chttp2_transport* t, s->published_metadata[i] = GPRC_METADATA_PUBLISHED_AT_CLOSE; } } - grpc_chttp2_maybe_complete_recv_initial_metadata(t, s); - grpc_chttp2_maybe_complete_recv_message(t, s); + grpc_chttp2_maybe_complete_recv_initial_metadata(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } if (became_closed) { - grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); - GRPC_CHTTP2_STREAM_UNREF(s, "chttp2"); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2"); } GRPC_ERROR_UNREF(error); } -static void close_from_api(grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_error* error) { +static void close_from_api(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_chttp2_stream* s, grpc_error* error) { grpc_slice hdr; grpc_slice status_hdr; grpc_slice http_status_hdr; @@ -2141,8 +2249,8 @@ static void close_from_api(grpc_chttp2_transport* t, grpc_chttp2_stream* s, uint32_t len = 0; grpc_status_code grpc_status; grpc_slice slice; - grpc_error_get_status(error, s->deadline, &grpc_status, &slice, nullptr, - nullptr); + grpc_error_get_status(exec_ctx, error, s->deadline, &grpc_status, &slice, + nullptr, nullptr); GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100); @@ -2284,11 +2392,13 @@ static void close_from_api(grpc_chttp2_transport* t, grpc_chttp2_stream* s, &t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR, &s->stats.outgoing)); - grpc_chttp2_mark_stream_closed(t, s, 1, 1, error); - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_CLOSE_FROM_API); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, 1, 1, error); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_CLOSE_FROM_API); } typedef struct { + grpc_exec_ctx* exec_ctx; grpc_error* error; grpc_chttp2_transport* t; } cancel_stream_cb_args; @@ -2296,11 +2406,13 @@ typedef struct { static void cancel_stream_cb(void* user_data, uint32_t key, void* stream) { cancel_stream_cb_args* args = (cancel_stream_cb_args*)user_data; grpc_chttp2_stream* s = (grpc_chttp2_stream*)stream; - grpc_chttp2_cancel_stream(args->t, s, GRPC_ERROR_REF(args->error)); + grpc_chttp2_cancel_stream(args->exec_ctx, args->t, s, + GRPC_ERROR_REF(args->error)); } -static void end_all_the_calls(grpc_chttp2_transport* t, grpc_error* error) { - cancel_stream_cb_args args = {error, t}; +static void end_all_the_calls(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_error* error) { + cancel_stream_cb_args args = {exec_ctx, error, t}; grpc_chttp2_stream_map_for_each(&t->stream_map, cancel_stream_cb, &args); GRPC_ERROR_UNREF(error); } @@ -2310,14 +2422,14 @@ static void end_all_the_calls(grpc_chttp2_transport* t, grpc_error* error) { */ template <class F> -static void WithUrgency(grpc_chttp2_transport* t, +static void WithUrgency(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_core::chttp2::FlowControlAction::Urgency urgency, grpc_chttp2_initiate_write_reason reason, F action) { switch (urgency) { case grpc_core::chttp2::FlowControlAction::Urgency::NO_ACTION_NEEDED: break; case grpc_core::chttp2::FlowControlAction::Urgency::UPDATE_IMMEDIATELY: - grpc_chttp2_initiate_write(t, reason); + grpc_chttp2_initiate_write(exec_ctx, t, reason); // fallthrough case grpc_core::chttp2::FlowControlAction::Urgency::QUEUE_UPDATE: action(); @@ -2326,27 +2438,31 @@ static void WithUrgency(grpc_chttp2_transport* t, } void grpc_chttp2_act_on_flowctl_action( - const grpc_core::chttp2::FlowControlAction& action, + grpc_exec_ctx* exec_ctx, const grpc_core::chttp2::FlowControlAction& action, grpc_chttp2_transport* t, grpc_chttp2_stream* s) { - WithUrgency(t, action.send_stream_update(), - GRPC_CHTTP2_INITIATE_WRITE_STREAM_FLOW_CONTROL, - [t, s]() { grpc_chttp2_mark_stream_writable(t, s); }); - WithUrgency(t, action.send_transport_update(), + WithUrgency( + exec_ctx, t, action.send_stream_update(), + GRPC_CHTTP2_INITIATE_WRITE_STREAM_FLOW_CONTROL, + [exec_ctx, t, s]() { grpc_chttp2_mark_stream_writable(exec_ctx, t, s); }); + WithUrgency(exec_ctx, t, action.send_transport_update(), GRPC_CHTTP2_INITIATE_WRITE_TRANSPORT_FLOW_CONTROL, []() {}); - WithUrgency(t, action.send_initial_window_update(), - GRPC_CHTTP2_INITIATE_WRITE_SEND_SETTINGS, [t, &action]() { - queue_setting_update(t, + WithUrgency(exec_ctx, t, action.send_initial_window_update(), + GRPC_CHTTP2_INITIATE_WRITE_SEND_SETTINGS, + [exec_ctx, t, &action]() { + queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, action.initial_window_size()); }); - WithUrgency(t, action.send_max_frame_size_update(), - GRPC_CHTTP2_INITIATE_WRITE_SEND_SETTINGS, [t, &action]() { - queue_setting_update(t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, - action.max_frame_size()); - }); + WithUrgency( + exec_ctx, t, action.send_max_frame_size_update(), + GRPC_CHTTP2_INITIATE_WRITE_SEND_SETTINGS, [exec_ctx, t, &action]() { + queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, + action.max_frame_size()); + }); } -static grpc_error* try_http_parsing(grpc_chttp2_transport* t) { +static grpc_error* try_http_parsing(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { grpc_http_parser parser; size_t i = 0; grpc_error* error = GRPC_ERROR_NONE; @@ -2375,7 +2491,8 @@ static grpc_error* try_http_parsing(grpc_chttp2_transport* t) { return error; } -static void read_action_locked(void* tp, grpc_error* error) { +static void read_action_locked(grpc_exec_ctx* exec_ctx, void* tp, + grpc_error* error) { GPR_TIMER_BEGIN("reading_action_locked", 0); grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp; @@ -2399,10 +2516,11 @@ static void read_action_locked(void* tp, grpc_error* error) { for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) { t->flow_control->bdp_estimator()->AddIncomingBytes( (int64_t)GRPC_SLICE_LENGTH(t->read_buffer.slices[i])); - errors[1] = grpc_chttp2_perform_read(t, t->read_buffer.slices[i]); + errors[1] = + grpc_chttp2_perform_read(exec_ctx, t, t->read_buffer.slices[i]); } if (errors[1] != GRPC_ERROR_NONE) { - errors[2] = try_http_parsing(t); + errors[2] = try_http_parsing(exec_ctx, t); GRPC_ERROR_UNREF(error); error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Failed parsing HTTP/2", errors, GPR_ARRAY_SIZE(errors)); @@ -2417,9 +2535,10 @@ static void read_action_locked(void* tp, grpc_error* error) { if (t->initial_window_update > 0) { grpc_chttp2_stream* s; while (grpc_chttp2_list_pop_stalled_by_stream(t, &s)) { - grpc_chttp2_mark_stream_writable(t, s); + grpc_chttp2_mark_stream_writable(exec_ctx, t, s); grpc_chttp2_initiate_write( - t, GRPC_CHTTP2_INITIATE_WRITE_FLOW_CONTROL_UNSTALLED_BY_SETTING); + exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_FLOW_CONTROL_UNSTALLED_BY_SETTING); } } t->initial_window_update = 0; @@ -2440,21 +2559,22 @@ static void read_action_locked(void* tp, grpc_error* error) { error = grpc_error_add_child(error, GRPC_ERROR_REF(t->goaway_error)); } - close_transport_locked(t, GRPC_ERROR_REF(error)); + close_transport_locked(exec_ctx, t, GRPC_ERROR_REF(error)); t->endpoint_reading = 0; } else if (t->closed_with_error == GRPC_ERROR_NONE) { keep_reading = true; GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading"); } - grpc_slice_buffer_reset_and_unref_internal(&t->read_buffer); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->read_buffer); if (keep_reading) { - grpc_endpoint_read(t->ep, &t->read_buffer, &t->read_action_locked); - grpc_chttp2_act_on_flowctl_action(t->flow_control->MakeAction(), t, - nullptr); - GRPC_CHTTP2_UNREF_TRANSPORT(t, "keep_reading"); + grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, + &t->read_action_locked); + grpc_chttp2_act_on_flowctl_action(exec_ctx, t->flow_control->MakeAction(), + t, nullptr); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading"); } else { - GRPC_CHTTP2_UNREF_TRANSPORT(t, "reading_action"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "reading_action"); } GPR_TIMER_END("post_reading_action_locked", 0); @@ -2466,12 +2586,15 @@ static void read_action_locked(void* tp, grpc_error* error) { // t is reffed prior to calling the first time, and once the callback chain // that kicks off finishes, it's unreffed -static void schedule_bdp_ping_locked(grpc_chttp2_transport* t) { +static void schedule_bdp_ping_locked(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { t->flow_control->bdp_estimator()->SchedulePing(); - send_ping_locked(t, &t->start_bdp_ping_locked, &t->finish_bdp_ping_locked); + send_ping_locked(exec_ctx, t, &t->start_bdp_ping_locked, + &t->finish_bdp_ping_locked); } -static void start_bdp_ping_locked(void* tp, grpc_error* error) { +static void start_bdp_ping_locked(grpc_exec_ctx* exec_ctx, void* tp, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp; if (grpc_http_trace.enabled()) { gpr_log(GPR_DEBUG, "%s: Start BDP ping err=%s", t->peer_string, @@ -2479,39 +2602,42 @@ static void start_bdp_ping_locked(void* tp, grpc_error* error) { } /* Reset the keepalive ping timer */ if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) { - grpc_timer_cancel(&t->keepalive_ping_timer); + grpc_timer_cancel(exec_ctx, &t->keepalive_ping_timer); } t->flow_control->bdp_estimator()->StartPing(); } -static void finish_bdp_ping_locked(void* tp, grpc_error* error) { +static void finish_bdp_ping_locked(grpc_exec_ctx* exec_ctx, void* tp, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp; if (grpc_http_trace.enabled()) { gpr_log(GPR_DEBUG, "%s: Complete BDP ping err=%s", t->peer_string, grpc_error_string(error)); } if (error != GRPC_ERROR_NONE) { - GRPC_CHTTP2_UNREF_TRANSPORT(t, "bdp_ping"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "bdp_ping"); return; } - grpc_millis next_ping = t->flow_control->bdp_estimator()->CompletePing(); - grpc_chttp2_act_on_flowctl_action(t->flow_control->PeriodicUpdate(), t, - nullptr); + grpc_millis next_ping = + t->flow_control->bdp_estimator()->CompletePing(exec_ctx); + grpc_chttp2_act_on_flowctl_action( + exec_ctx, t->flow_control->PeriodicUpdate(exec_ctx), t, nullptr); GPR_ASSERT(!t->have_next_bdp_ping_timer); t->have_next_bdp_ping_timer = true; - grpc_timer_init(&t->next_bdp_ping_timer, next_ping, + grpc_timer_init(exec_ctx, &t->next_bdp_ping_timer, next_ping, &t->next_bdp_ping_timer_expired_locked); } -static void next_bdp_ping_timer_expired_locked(void* tp, grpc_error* error) { +static void next_bdp_ping_timer_expired_locked(grpc_exec_ctx* exec_ctx, + void* tp, grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp; GPR_ASSERT(t->have_next_bdp_ping_timer); t->have_next_bdp_ping_timer = false; if (error != GRPC_ERROR_NONE) { - GRPC_CHTTP2_UNREF_TRANSPORT(t, "bdp_ping"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "bdp_ping"); return; } - schedule_bdp_ping_locked(t); + schedule_bdp_ping_locked(exec_ctx, t); } void grpc_chttp2_config_default_keepalive_args(grpc_channel_args* args, @@ -2572,7 +2698,8 @@ void grpc_chttp2_config_default_keepalive_args(grpc_channel_args* args, } } -static void init_keepalive_ping_locked(void* arg, grpc_error* error) { +static void init_keepalive_ping_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)arg; GPR_ASSERT(t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING); if (t->destroying || t->closed_with_error != GRPC_ERROR_NONE) { @@ -2582,55 +2709,59 @@ static void init_keepalive_ping_locked(void* arg, grpc_error* error) { grpc_chttp2_stream_map_size(&t->stream_map) > 0) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_PINGING; GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive ping end"); - send_ping_locked(t, &t->start_keepalive_ping_locked, + send_ping_locked(exec_ctx, t, &t->start_keepalive_ping_locked, &t->finish_keepalive_ping_locked); - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_KEEPALIVE_PING); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_KEEPALIVE_PING); } else { GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping"); - grpc_timer_init(&t->keepalive_ping_timer, - grpc_core::ExecCtx::Get()->Now() + t->keepalive_time, + grpc_timer_init(exec_ctx, &t->keepalive_ping_timer, + grpc_exec_ctx_now(exec_ctx) + t->keepalive_time, &t->init_keepalive_ping_locked); } } else if (error == GRPC_ERROR_CANCELLED) { /* The keepalive ping timer may be cancelled by bdp */ GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping"); - grpc_timer_init(&t->keepalive_ping_timer, - grpc_core::ExecCtx::Get()->Now() + t->keepalive_time, + grpc_timer_init(exec_ctx, &t->keepalive_ping_timer, + grpc_exec_ctx_now(exec_ctx) + t->keepalive_time, &t->init_keepalive_ping_locked); } - GRPC_CHTTP2_UNREF_TRANSPORT(t, "init keepalive ping"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "init keepalive ping"); } -static void start_keepalive_ping_locked(void* arg, grpc_error* error) { +static void start_keepalive_ping_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)arg; GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive watchdog"); - grpc_timer_init(&t->keepalive_watchdog_timer, - grpc_core::ExecCtx::Get()->Now() + t->keepalive_time, + grpc_timer_init(exec_ctx, &t->keepalive_watchdog_timer, + grpc_exec_ctx_now(exec_ctx) + t->keepalive_time, &t->keepalive_watchdog_fired_locked); } -static void finish_keepalive_ping_locked(void* arg, grpc_error* error) { +static void finish_keepalive_ping_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)arg; if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING; - grpc_timer_cancel(&t->keepalive_watchdog_timer); + grpc_timer_cancel(exec_ctx, &t->keepalive_watchdog_timer); GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping"); - grpc_timer_init(&t->keepalive_ping_timer, - grpc_core::ExecCtx::Get()->Now() + t->keepalive_time, + grpc_timer_init(exec_ctx, &t->keepalive_ping_timer, + grpc_exec_ctx_now(exec_ctx) + t->keepalive_time, &t->init_keepalive_ping_locked); } } - GRPC_CHTTP2_UNREF_TRANSPORT(t, "keepalive ping end"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keepalive ping end"); } -static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) { +static void keepalive_watchdog_fired_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)arg; if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; close_transport_locked( - t, + exec_ctx, t, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "keepalive watchdog timeout"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL)); @@ -2643,67 +2774,71 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) { t->keepalive_state, GRPC_CHTTP2_KEEPALIVE_STATE_PINGING); } } - GRPC_CHTTP2_UNREF_TRANSPORT(t, "keepalive watchdog"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keepalive watchdog"); } /******************************************************************************* * CALLBACK LOOP */ -static void connectivity_state_set(grpc_chttp2_transport* t, +static void connectivity_state_set(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_connectivity_state state, grpc_error* error, const char* reason) { GRPC_CHTTP2_IF_TRACING( gpr_log(GPR_DEBUG, "set connectivity_state=%d", state)); - grpc_connectivity_state_set(&t->channel_callback.state_tracker, state, error, - reason); + grpc_connectivity_state_set(exec_ctx, &t->channel_callback.state_tracker, + state, error, reason); } /******************************************************************************* * POLLSET STUFF */ -static void set_pollset(grpc_transport* gt, grpc_stream* gs, - grpc_pollset* pollset) { +static void set_pollset(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_pollset* pollset) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)gt; - grpc_endpoint_add_to_pollset(t->ep, pollset); + grpc_endpoint_add_to_pollset(exec_ctx, t->ep, pollset); } -static void set_pollset_set(grpc_transport* gt, grpc_stream* gs, - grpc_pollset_set* pollset_set) { +static void set_pollset_set(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_pollset_set* pollset_set) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)gt; - grpc_endpoint_add_to_pollset_set(t->ep, pollset_set); + grpc_endpoint_add_to_pollset_set(exec_ctx, t->ep, pollset_set); } /******************************************************************************* * BYTE STREAM */ -static void reset_byte_stream(void* arg, grpc_error* error) { +static void reset_byte_stream(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { grpc_chttp2_stream* s = (grpc_chttp2_stream*)arg; s->pending_byte_stream = false; if (error == GRPC_ERROR_NONE) { - grpc_chttp2_maybe_complete_recv_message(s->t, s); - grpc_chttp2_maybe_complete_recv_trailing_metadata(s->t, s); + grpc_chttp2_maybe_complete_recv_message(exec_ctx, s->t, s); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, s->t, s); } else { GPR_ASSERT(error != GRPC_ERROR_NONE); - GRPC_CLOSURE_SCHED(s->on_next, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); s->on_next = nullptr; GRPC_ERROR_UNREF(s->byte_stream_error); s->byte_stream_error = GRPC_ERROR_NONE; - grpc_chttp2_cancel_stream(s->t, s, GRPC_ERROR_REF(error)); + grpc_chttp2_cancel_stream(exec_ctx, s->t, s, GRPC_ERROR_REF(error)); s->byte_stream_error = GRPC_ERROR_REF(error); } } -static void incoming_byte_stream_unref(grpc_chttp2_incoming_byte_stream* bs) { +static void incoming_byte_stream_unref(grpc_exec_ctx* exec_ctx, + grpc_chttp2_incoming_byte_stream* bs) { if (gpr_unref(&bs->refs)) { gpr_free(bs); } } -static void incoming_byte_stream_next_locked(void* argp, +static void incoming_byte_stream_next_locked(grpc_exec_ctx* exec_ctx, + void* argp, grpc_error* error_ignored) { grpc_chttp2_incoming_byte_stream* bs = (grpc_chttp2_incoming_byte_stream*)argp; @@ -2714,29 +2849,30 @@ static void incoming_byte_stream_next_locked(void* argp, if (!s->read_closed) { s->flow_control->IncomingByteStreamUpdate(bs->next_action.max_size_hint, cur_length); - grpc_chttp2_act_on_flowctl_action(s->flow_control->MakeAction(), t, s); + grpc_chttp2_act_on_flowctl_action(exec_ctx, s->flow_control->MakeAction(), + t, s); } GPR_ASSERT(s->unprocessed_incoming_frames_buffer.length == 0); if (s->frame_storage.length > 0) { grpc_slice_buffer_swap(&s->frame_storage, &s->unprocessed_incoming_frames_buffer); s->unprocessed_incoming_frames_decompressed = false; - GRPC_CLOSURE_SCHED(bs->next_action.on_complete, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_NONE); } else if (s->byte_stream_error != GRPC_ERROR_NONE) { - GRPC_CLOSURE_SCHED(bs->next_action.on_complete, + GRPC_CLOSURE_SCHED(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_REF(s->byte_stream_error)); if (s->data_parser.parsing_frame != nullptr) { - incoming_byte_stream_unref(s->data_parser.parsing_frame); + incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame); s->data_parser.parsing_frame = nullptr; } } else if (s->read_closed) { if (bs->remaining_bytes != 0) { s->byte_stream_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); - GRPC_CLOSURE_SCHED(bs->next_action.on_complete, + GRPC_CLOSURE_SCHED(exec_ctx, bs->next_action.on_complete, GRPC_ERROR_REF(s->byte_stream_error)); if (s->data_parser.parsing_frame != nullptr) { - incoming_byte_stream_unref(s->data_parser.parsing_frame); + incoming_byte_stream_unref(exec_ctx, s->data_parser.parsing_frame); s->data_parser.parsing_frame = nullptr; } } else { @@ -2746,10 +2882,11 @@ static void incoming_byte_stream_next_locked(void* argp, } else { s->on_next = bs->next_action.on_complete; } - incoming_byte_stream_unref(bs); + incoming_byte_stream_unref(exec_ctx, bs); } -static bool incoming_byte_stream_next(grpc_byte_stream* byte_stream, +static bool incoming_byte_stream_next(grpc_exec_ctx* exec_ctx, + grpc_byte_stream* byte_stream, size_t max_size_hint, grpc_closure* on_complete) { GPR_TIMER_BEGIN("incoming_byte_stream_next", 0); @@ -2764,6 +2901,7 @@ static bool incoming_byte_stream_next(grpc_byte_stream* byte_stream, bs->next_action.max_size_hint = max_size_hint; bs->next_action.on_complete = on_complete; GRPC_CLOSURE_SCHED( + exec_ctx, GRPC_CLOSURE_INIT(&bs->next_action.closure, incoming_byte_stream_next_locked, bs, grpc_combiner_scheduler(bs->transport->combiner)), @@ -2773,7 +2911,8 @@ static bool incoming_byte_stream_next(grpc_byte_stream* byte_stream, } } -static grpc_error* incoming_byte_stream_pull(grpc_byte_stream* byte_stream, +static grpc_error* incoming_byte_stream_pull(grpc_exec_ctx* exec_ctx, + grpc_byte_stream* byte_stream, grpc_slice* slice) { GPR_TIMER_BEGIN("incoming_byte_stream_pull", 0); grpc_chttp2_incoming_byte_stream* bs = @@ -2809,28 +2948,31 @@ static grpc_error* incoming_byte_stream_pull(grpc_byte_stream* byte_stream, } } error = grpc_deframe_unprocessed_incoming_frames( - &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, slice, - nullptr); + exec_ctx, &s->data_parser, s, &s->unprocessed_incoming_frames_buffer, + slice, nullptr); if (error != GRPC_ERROR_NONE) { return error; } } else { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Truncated message"); - GRPC_CLOSURE_SCHED(&s->reset_byte_stream, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); return error; } GPR_TIMER_END("incoming_byte_stream_pull", 0); return GRPC_ERROR_NONE; } -static void incoming_byte_stream_destroy_locked(void* byte_stream, +static void incoming_byte_stream_destroy_locked(grpc_exec_ctx* exec_ctx, + void* byte_stream, grpc_error* error_ignored); -static void incoming_byte_stream_destroy(grpc_byte_stream* byte_stream) { +static void incoming_byte_stream_destroy(grpc_exec_ctx* exec_ctx, + grpc_byte_stream* byte_stream) { GPR_TIMER_BEGIN("incoming_byte_stream_destroy", 0); grpc_chttp2_incoming_byte_stream* bs = (grpc_chttp2_incoming_byte_stream*)byte_stream; GRPC_CLOSURE_SCHED( + exec_ctx, GRPC_CLOSURE_INIT(&bs->destroy_action, incoming_byte_stream_destroy_locked, bs, grpc_combiner_scheduler(bs->transport->combiner)), @@ -2839,28 +2981,30 @@ static void incoming_byte_stream_destroy(grpc_byte_stream* byte_stream) { } static void incoming_byte_stream_publish_error( - grpc_chttp2_incoming_byte_stream* bs, grpc_error* error) { + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_byte_stream* bs, + grpc_error* error) { grpc_chttp2_stream* s = bs->stream; GPR_ASSERT(error != GRPC_ERROR_NONE); - GRPC_CLOSURE_SCHED(s->on_next, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(exec_ctx, s->on_next, GRPC_ERROR_REF(error)); s->on_next = nullptr; GRPC_ERROR_UNREF(s->byte_stream_error); s->byte_stream_error = GRPC_ERROR_REF(error); - grpc_chttp2_cancel_stream(bs->transport, bs->stream, GRPC_ERROR_REF(error)); + grpc_chttp2_cancel_stream(exec_ctx, bs->transport, bs->stream, + GRPC_ERROR_REF(error)); } grpc_error* grpc_chttp2_incoming_byte_stream_push( - grpc_chttp2_incoming_byte_stream* bs, grpc_slice slice, - grpc_slice* slice_out) { + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_byte_stream* bs, + grpc_slice slice, grpc_slice* slice_out) { grpc_chttp2_stream* s = bs->stream; if (bs->remaining_bytes < GRPC_SLICE_LENGTH(slice)) { grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Too many bytes in stream"); - GRPC_CLOSURE_SCHED(&s->reset_byte_stream, GRPC_ERROR_REF(error)); - grpc_slice_unref_internal(slice); + GRPC_CLOSURE_SCHED(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); + grpc_slice_unref_internal(exec_ctx, slice); return error; } else { bs->remaining_bytes -= (uint32_t)GRPC_SLICE_LENGTH(slice); @@ -2872,8 +3016,8 @@ grpc_error* grpc_chttp2_incoming_byte_stream_push( } grpc_error* grpc_chttp2_incoming_byte_stream_finished( - grpc_chttp2_incoming_byte_stream* bs, grpc_error* error, - bool reset_on_error) { + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_byte_stream* bs, + grpc_error* error, bool reset_on_error) { grpc_chttp2_stream* s = bs->stream; if (error == GRPC_ERROR_NONE) { @@ -2882,25 +3026,27 @@ grpc_error* grpc_chttp2_incoming_byte_stream_finished( } } if (error != GRPC_ERROR_NONE && reset_on_error) { - GRPC_CLOSURE_SCHED(&s->reset_byte_stream, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(exec_ctx, &s->reset_byte_stream, GRPC_ERROR_REF(error)); } - incoming_byte_stream_unref(bs); + incoming_byte_stream_unref(exec_ctx, bs); return error; } -static void incoming_byte_stream_shutdown(grpc_byte_stream* byte_stream, +static void incoming_byte_stream_shutdown(grpc_exec_ctx* exec_ctx, + grpc_byte_stream* byte_stream, grpc_error* error) { grpc_chttp2_incoming_byte_stream* bs = (grpc_chttp2_incoming_byte_stream*)byte_stream; GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished( - bs, error, true /* reset_on_error */)); + exec_ctx, bs, error, true /* reset_on_error */)); } static const grpc_byte_stream_vtable grpc_chttp2_incoming_byte_stream_vtable = { incoming_byte_stream_next, incoming_byte_stream_pull, incoming_byte_stream_shutdown, incoming_byte_stream_destroy}; -static void incoming_byte_stream_destroy_locked(void* byte_stream, +static void incoming_byte_stream_destroy_locked(grpc_exec_ctx* exec_ctx, + void* byte_stream, grpc_error* error_ignored) { grpc_chttp2_incoming_byte_stream* bs = (grpc_chttp2_incoming_byte_stream*)byte_stream; @@ -2908,15 +3054,15 @@ static void incoming_byte_stream_destroy_locked(void* byte_stream, grpc_chttp2_transport* t = s->t; GPR_ASSERT(bs->base.vtable == &grpc_chttp2_incoming_byte_stream_vtable); - incoming_byte_stream_unref(bs); + incoming_byte_stream_unref(exec_ctx, bs); s->pending_byte_stream = false; - grpc_chttp2_maybe_complete_recv_message(t, s); - grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); + grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); } grpc_chttp2_incoming_byte_stream* grpc_chttp2_incoming_byte_stream_create( - grpc_chttp2_transport* t, grpc_chttp2_stream* s, uint32_t frame_size, - uint32_t flags) { + grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_chttp2_stream* s, + uint32_t frame_size, uint32_t flags) { grpc_chttp2_incoming_byte_stream* incoming_byte_stream = (grpc_chttp2_incoming_byte_stream*)gpr_malloc( sizeof(*incoming_byte_stream)); @@ -2936,25 +3082,30 @@ grpc_chttp2_incoming_byte_stream* grpc_chttp2_incoming_byte_stream_create( * RESOURCE QUOTAS */ -static void post_benign_reclaimer(grpc_chttp2_transport* t) { +static void post_benign_reclaimer(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { if (!t->benign_reclaimer_registered) { t->benign_reclaimer_registered = true; GRPC_CHTTP2_REF_TRANSPORT(t, "benign_reclaimer"); - grpc_resource_user_post_reclaimer(grpc_endpoint_get_resource_user(t->ep), + grpc_resource_user_post_reclaimer(exec_ctx, + grpc_endpoint_get_resource_user(t->ep), false, &t->benign_reclaimer_locked); } } -static void post_destructive_reclaimer(grpc_chttp2_transport* t) { +static void post_destructive_reclaimer(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { if (!t->destructive_reclaimer_registered) { t->destructive_reclaimer_registered = true; GRPC_CHTTP2_REF_TRANSPORT(t, "destructive_reclaimer"); - grpc_resource_user_post_reclaimer(grpc_endpoint_get_resource_user(t->ep), + grpc_resource_user_post_reclaimer(exec_ctx, + grpc_endpoint_get_resource_user(t->ep), true, &t->destructive_reclaimer_locked); } } -static void benign_reclaimer_locked(void* arg, grpc_error* error) { +static void benign_reclaimer_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)arg; if (error == GRPC_ERROR_NONE && grpc_chttp2_stream_map_size(&t->stream_map) == 0) { @@ -2964,7 +3115,7 @@ static void benign_reclaimer_locked(void* arg, grpc_error* error) { gpr_log(GPR_DEBUG, "HTTP2: %s - send goaway to free memory", t->peer_string); } - send_goaway(t, + send_goaway(exec_ctx, t, grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"), GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM)); @@ -2977,12 +3128,13 @@ static void benign_reclaimer_locked(void* arg, grpc_error* error) { t->benign_reclaimer_registered = false; if (error != GRPC_ERROR_CANCELLED) { grpc_resource_user_finish_reclamation( - grpc_endpoint_get_resource_user(t->ep)); + exec_ctx, grpc_endpoint_get_resource_user(t->ep)); } - GRPC_CHTTP2_UNREF_TRANSPORT(t, "benign_reclaimer"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "benign_reclaimer"); } -static void destructive_reclaimer_locked(void* arg, grpc_error* error) { +static void destructive_reclaimer_locked(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)arg; size_t n = grpc_chttp2_stream_map_size(&t->stream_map); t->destructive_reclaimer_registered = false; @@ -2994,7 +3146,7 @@ static void destructive_reclaimer_locked(void* arg, grpc_error* error) { s->id); } grpc_chttp2_cancel_stream( - t, s, + exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"), GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM)); @@ -3003,14 +3155,14 @@ static void destructive_reclaimer_locked(void* arg, grpc_error* error) { there are more streams left, we can immediately post a new reclaimer in case the resource quota needs to free more memory */ - post_destructive_reclaimer(t); + post_destructive_reclaimer(exec_ctx, t); } } if (error != GRPC_ERROR_CANCELLED) { grpc_resource_user_finish_reclamation( - grpc_endpoint_get_resource_user(t->ep)); + exec_ctx, grpc_endpoint_get_resource_user(t->ep)); } - GRPC_CHTTP2_UNREF_TRANSPORT(t, "destructive_reclaimer"); + GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destructive_reclaimer"); } /******************************************************************************* @@ -3064,7 +3216,8 @@ const char* grpc_chttp2_initiate_write_reason_string( GPR_UNREACHABLE_CODE(return "unknown"); } -static grpc_endpoint* chttp2_get_endpoint(grpc_transport* t) { +static grpc_endpoint* chttp2_get_endpoint(grpc_exec_ctx* exec_ctx, + grpc_transport* t) { return ((grpc_chttp2_transport*)t)->ep; } @@ -3082,16 +3235,17 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), static const grpc_transport_vtable* get_vtable(void) { return &vtable; } grpc_transport* grpc_create_chttp2_transport( - const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client) { + grpc_exec_ctx* exec_ctx, const grpc_channel_args* channel_args, + grpc_endpoint* ep, bool is_client) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)gpr_zalloc(sizeof(grpc_chttp2_transport)); - init_transport(t, channel_args, ep, is_client); + init_transport(exec_ctx, t, channel_args, ep, is_client); return &t->base; } void grpc_chttp2_transport_start_reading( - grpc_transport* transport, grpc_slice_buffer* read_buffer, - grpc_closure* notify_on_receive_settings) { + grpc_exec_ctx* exec_ctx, grpc_transport* transport, + grpc_slice_buffer* read_buffer, grpc_closure* notify_on_receive_settings) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)transport; GRPC_CHTTP2_REF_TRANSPORT( t, "reading_action"); /* matches unref inside reading_action */ @@ -3100,5 +3254,5 @@ void grpc_chttp2_transport_start_reading( gpr_free(read_buffer); } t->notify_on_receive_settings = notify_on_receive_settings; - GRPC_CLOSURE_SCHED(&t->read_action_locked, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(exec_ctx, &t->read_action_locked, GRPC_ERROR_NONE); } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h index 596ababb19..bd72e07bab 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -28,14 +28,15 @@ extern grpc_core::TraceFlag grpc_trace_http2_stream_state; extern grpc_core::DebugOnlyTraceFlag grpc_trace_chttp2_refcount; grpc_transport* grpc_create_chttp2_transport( - const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client); + grpc_exec_ctx* exec_ctx, const grpc_channel_args* channel_args, + grpc_endpoint* ep, bool is_client); /// Takes ownership of \a read_buffer, which (if non-NULL) contains /// leftover bytes previously read from the endpoint (e.g., by handshakers). /// If non-null, \a notify_on_receive_settings will be scheduled when /// HTTP/2 settings are received from the peer. void grpc_chttp2_transport_start_reading( - grpc_transport* transport, grpc_slice_buffer* read_buffer, - grpc_closure* notify_on_receive_settings); + grpc_exec_ctx* exec_ctx, grpc_transport* transport, + grpc_slice_buffer* read_buffer, grpc_closure* notify_on_receive_settings); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CHTTP2_TRANSPORT_H */ diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc index ca48cc7e0a..8a057bd9ff 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.cc +++ b/src/core/ext/transport/chttp2/transport/flow_control.cc @@ -149,7 +149,8 @@ void FlowControlAction::Trace(grpc_chttp2_transport* t) const { gpr_free(mf_str); } -TransportFlowControl::TransportFlowControl(const grpc_chttp2_transport* t, +TransportFlowControl::TransportFlowControl(grpc_exec_ctx* exec_ctx, + const grpc_chttp2_transport* t, bool enable_bdp_probe) : t_(t), enable_bdp_probe_(enable_bdp_probe), @@ -162,7 +163,7 @@ TransportFlowControl::TransportFlowControl(const grpc_chttp2_transport* t, .set_min_control_value(-1) .set_max_control_value(25) .set_integral_range(10)), - last_pid_update_(grpc_core::ExecCtx::Get()->Now()) {} + last_pid_update_(grpc_exec_ctx_now(exec_ctx)) {} uint32_t TransportFlowControl::MaybeSendUpdate(bool writing_anyway) { FlowControlTrace trace("t updt sent", this, nullptr); @@ -307,8 +308,9 @@ double TransportFlowControl::TargetLogBdp() { 1 + log2(bdp_estimator_.EstimateBdp())); } -double TransportFlowControl::SmoothLogBdp(double value) { - grpc_millis now = grpc_core::ExecCtx::Get()->Now(); +double TransportFlowControl::SmoothLogBdp(grpc_exec_ctx* exec_ctx, + double value) { + grpc_millis now = grpc_exec_ctx_now(exec_ctx); double bdp_error = value - pid_controller_.last_control_value(); const double dt = (double)(now - last_pid_update_) * 1e-3; last_pid_update_ = now; @@ -329,14 +331,15 @@ FlowControlAction::Urgency TransportFlowControl::DeltaUrgency( } } -FlowControlAction TransportFlowControl::PeriodicUpdate() { +FlowControlAction TransportFlowControl::PeriodicUpdate( + grpc_exec_ctx* exec_ctx) { FlowControlAction action; if (enable_bdp_probe_) { // get bdp estimate and update initial_window accordingly. // target might change based on how much memory pressure we are under // TODO(ncteisen): experiment with setting target to be huge under low // memory pressure. - const double target = pow(2, SmoothLogBdp(TargetLogBdp())); + const double target = pow(2, SmoothLogBdp(exec_ctx, TargetLogBdp())); // Though initial window 'could' drop to 0, we keep the floor at 128 target_initial_window_size_ = (int32_t)GPR_CLAMP(target, 128, INT32_MAX); diff --git a/src/core/ext/transport/chttp2/transport/flow_control.h b/src/core/ext/transport/chttp2/transport/flow_control.h index 8306047dbc..2515c94309 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.h +++ b/src/core/ext/transport/chttp2/transport/flow_control.h @@ -134,7 +134,8 @@ class FlowControlTrace { class TransportFlowControl { public: - TransportFlowControl(const grpc_chttp2_transport* t, bool enable_bdp_probe); + TransportFlowControl(grpc_exec_ctx* exec_ctx, const grpc_chttp2_transport* t, + bool enable_bdp_probe); ~TransportFlowControl() {} bool bdp_probe() const { return enable_bdp_probe_; } @@ -152,7 +153,7 @@ class TransportFlowControl { // Call periodically (at a low-ish rate, 100ms - 10s makes sense) // to perform more complex flow control calculations and return an action // to let chttp2 change its parameters - FlowControlAction PeriodicUpdate(); + FlowControlAction PeriodicUpdate(grpc_exec_ctx* exec_ctx); void StreamSentData(int64_t size) { remote_window_ -= size; } @@ -211,7 +212,7 @@ class TransportFlowControl { private: friend class ::grpc::testing::TrickledCHTTP2; double TargetLogBdp(); - double SmoothLogBdp(double value); + double SmoothLogBdp(grpc_exec_ctx* exec_ctx, double value); FlowControlAction::Urgency DeltaUrgency(int32_t value, grpc_chttp2_setting_id setting_id); diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 9b3a6acc9e..f0c3b55792 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -36,10 +36,11 @@ grpc_error* grpc_chttp2_data_parser_init(grpc_chttp2_data_parser* parser) { return GRPC_ERROR_NONE; } -void grpc_chttp2_data_parser_destroy(grpc_chttp2_data_parser* parser) { +void grpc_chttp2_data_parser_destroy(grpc_exec_ctx* exec_ctx, + grpc_chttp2_data_parser* parser) { if (parser->parsing_frame != nullptr) { GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished( - parser->parsing_frame, + exec_ctx, parser->parsing_frame, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Parser destroyed"), false)); } GRPC_ERROR_UNREF(parser->error); @@ -97,7 +98,7 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer* inbuf, } grpc_error* grpc_deframe_unprocessed_incoming_frames( - grpc_chttp2_data_parser* p, grpc_chttp2_stream* s, + grpc_exec_ctx* exec_ctx, grpc_chttp2_data_parser* p, grpc_chttp2_stream* s, grpc_slice_buffer* slices, grpc_slice* slice_out, grpc_byte_stream** stream_out) { grpc_error* error = GRPC_ERROR_NONE; @@ -117,14 +118,14 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( char* msg; if (cur == end) { - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); continue; } switch (p->state) { case GRPC_CHTTP2_DATA_ERROR: p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_REF(p->error); case GRPC_CHTTP2_DATA_FH_0: s->stats.incoming.framing_bytes++; @@ -149,12 +150,12 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_REF(p->error); } if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_1; - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); continue; } /* fallthrough */ @@ -163,7 +164,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size = ((uint32_t)*cur) << 24; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_2; - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); continue; } /* fallthrough */ @@ -172,7 +173,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size |= ((uint32_t)*cur) << 16; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_3; - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); continue; } /* fallthrough */ @@ -181,7 +182,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size |= ((uint32_t)*cur) << 8; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_4; - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); continue; } /* fallthrough */ @@ -197,11 +198,11 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( message_flags |= GRPC_WRITE_INTERNAL_COMPRESS; } p->parsing_frame = grpc_chttp2_incoming_byte_stream_create( - t, s, p->frame_size, message_flags); + exec_ctx, t, s, p->frame_size, message_flags); *stream_out = &p->parsing_frame->base; if (p->parsing_frame->remaining_bytes == 0) { GRPC_ERROR_UNREF(grpc_chttp2_incoming_byte_stream_finished( - p->parsing_frame, GRPC_ERROR_NONE, true)); + exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true)); p->parsing_frame = nullptr; p->state = GRPC_CHTTP2_DATA_FH_0; } @@ -212,64 +213,64 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( slices, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); } - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; case GRPC_CHTTP2_DATA_FRAME: { GPR_ASSERT(p->parsing_frame != nullptr); GPR_ASSERT(slice_out != nullptr); if (cur == end) { - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); continue; } uint32_t remaining = (uint32_t)(end - cur); if (remaining == p->frame_size) { s->stats.incoming.data_bytes += remaining; if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( - p->parsing_frame, + exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)), slice_out))) { - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); return error; } if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_finished( - p->parsing_frame, GRPC_ERROR_NONE, true))) { - grpc_slice_unref_internal(slice); + exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true))) { + grpc_slice_unref_internal(exec_ctx, slice); return error; } p->parsing_frame = nullptr; p->state = GRPC_CHTTP2_DATA_FH_0; - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } else if (remaining < p->frame_size) { s->stats.incoming.data_bytes += remaining; if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_push( - p->parsing_frame, + exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg)), slice_out))) { return error; } p->frame_size -= remaining; - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } else { GPR_ASSERT(remaining > p->frame_size); s->stats.incoming.data_bytes += p->frame_size; if (GRPC_ERROR_NONE != (grpc_chttp2_incoming_byte_stream_push( - p->parsing_frame, + exec_ctx, p->parsing_frame, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(cur + p->frame_size - beg)), slice_out))) { - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); return error; } if (GRPC_ERROR_NONE != (error = grpc_chttp2_incoming_byte_stream_finished( - p->parsing_frame, GRPC_ERROR_NONE, true))) { - grpc_slice_unref_internal(slice); + exec_ctx, p->parsing_frame, GRPC_ERROR_NONE, true))) { + grpc_slice_unref_internal(exec_ctx, slice); return error; } p->parsing_frame = nullptr; @@ -278,7 +279,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( grpc_slice_buffer_undo_take_first( slices, grpc_slice_sub(slice, (size_t)(cur - beg), (size_t)(end - beg))); - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); return GRPC_ERROR_NONE; } } @@ -288,19 +289,19 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( return GRPC_ERROR_NONE; } -grpc_error* grpc_chttp2_data_parser_parse(void* parser, +grpc_error* grpc_chttp2_data_parser_parse(grpc_exec_ctx* exec_ctx, void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last) { if (!s->pending_byte_stream) { grpc_slice_ref_internal(slice); grpc_slice_buffer_add(&s->frame_storage, slice); - grpc_chttp2_maybe_complete_recv_message(t, s); + grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); } else if (s->on_next) { GPR_ASSERT(s->frame_storage.length == 0); grpc_slice_ref_internal(slice); grpc_slice_buffer_add(&s->unprocessed_incoming_frames_buffer, slice); - GRPC_CLOSURE_SCHED(s->on_next, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(exec_ctx, s->on_next, GRPC_ERROR_NONE); s->on_next = nullptr; s->unprocessed_incoming_frames_decompressed = false; } else { @@ -309,7 +310,8 @@ grpc_error* grpc_chttp2_data_parser_parse(void* parser, } if (is_last && s->received_last_frame) { - grpc_chttp2_mark_stream_closed(t, s, true, false, GRPC_ERROR_NONE); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, + GRPC_ERROR_NONE); } return GRPC_ERROR_NONE; diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index 964cc59b1b..4de553ea42 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -54,7 +54,8 @@ typedef struct { /* initialize per-stream state for data frame parsing */ grpc_error* grpc_chttp2_data_parser_init(grpc_chttp2_data_parser* parser); -void grpc_chttp2_data_parser_destroy(grpc_chttp2_data_parser* parser); +void grpc_chttp2_data_parser_destroy(grpc_exec_ctx* exec_ctx, + grpc_chttp2_data_parser* parser); /* start processing a new data frame */ grpc_error* grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser* parser, @@ -64,7 +65,7 @@ grpc_error* grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser* parser, /* handle a slice of a data frame - is_last indicates the last slice of a frame */ -grpc_error* grpc_chttp2_data_parser_parse(void* parser, +grpc_error* grpc_chttp2_data_parser_parse(grpc_exec_ctx* exec_ctx, void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last); @@ -75,7 +76,7 @@ void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer* inbuf, grpc_slice_buffer* outbuf); grpc_error* grpc_deframe_unprocessed_incoming_frames( - grpc_chttp2_data_parser* p, grpc_chttp2_stream* s, + grpc_exec_ctx* exec_ctx, grpc_chttp2_data_parser* p, grpc_chttp2_stream* s, grpc_slice_buffer* slices, grpc_slice* slice_out, grpc_byte_stream** stream_out); diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.cc b/src/core/ext/transport/chttp2/transport/frame_goaway.cc index b60b4227fe..a2ce709a2e 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.cc +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.cc @@ -52,7 +52,8 @@ grpc_error* grpc_chttp2_goaway_parser_begin_frame(grpc_chttp2_goaway_parser* p, return GRPC_ERROR_NONE; } -grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, +grpc_error* grpc_chttp2_goaway_parser_parse(grpc_exec_ctx* exec_ctx, + void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last) { @@ -134,7 +135,7 @@ grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, p->state = GRPC_CHTTP2_GOAWAY_DEBUG; if (is_last) { grpc_chttp2_add_incoming_goaway( - t, (uint32_t)p->error_code, + exec_ctx, t, (uint32_t)p->error_code, grpc_slice_new(p->debug_data, p->debug_length, gpr_free)); p->debug_data = nullptr; } diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.h b/src/core/ext/transport/chttp2/transport/frame_goaway.h index 064d39ac59..743e763342 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.h +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.h @@ -50,7 +50,8 @@ void grpc_chttp2_goaway_parser_init(grpc_chttp2_goaway_parser* p); void grpc_chttp2_goaway_parser_destroy(grpc_chttp2_goaway_parser* p); grpc_error* grpc_chttp2_goaway_parser_begin_frame( grpc_chttp2_goaway_parser* parser, uint32_t length, uint8_t flags); -grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, +grpc_error* grpc_chttp2_goaway_parser_parse(grpc_exec_ctx* exec_ctx, + void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last); diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.cc b/src/core/ext/transport/chttp2/transport/frame_ping.cc index 298a56721a..d0feb51922 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.cc +++ b/src/core/ext/transport/chttp2/transport/frame_ping.cc @@ -68,7 +68,7 @@ grpc_error* grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser* parser, return GRPC_ERROR_NONE; } -grpc_error* grpc_chttp2_ping_parser_parse(void* parser, +grpc_error* grpc_chttp2_ping_parser_parse(grpc_exec_ctx* exec_ctx, void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last) { @@ -86,10 +86,10 @@ grpc_error* grpc_chttp2_ping_parser_parse(void* parser, if (p->byte == 8) { GPR_ASSERT(is_last); if (p->is_ack) { - grpc_chttp2_ack_ping(t, p->opaque_8bytes); + grpc_chttp2_ack_ping(exec_ctx, t, p->opaque_8bytes); } else { if (!t->is_client) { - grpc_millis now = grpc_core::ExecCtx::Get()->Now(); + grpc_millis now = grpc_exec_ctx_now(exec_ctx); grpc_millis next_allowed_ping = t->ping_recv_state.last_ping_recv_time + t->ping_policy.min_recv_ping_interval_without_data; @@ -104,7 +104,7 @@ grpc_error* grpc_chttp2_ping_parser_parse(void* parser, } if (next_allowed_ping > now) { - grpc_chttp2_add_ping_strike(t); + grpc_chttp2_add_ping_strike(exec_ctx, t); } t->ping_recv_state.last_ping_recv_time = now; @@ -116,7 +116,8 @@ grpc_error* grpc_chttp2_ping_parser_parse(void* parser, t->ping_acks, t->ping_ack_capacity * sizeof(*t->ping_acks)); } t->ping_acks[t->ping_ack_count++] = p->opaque_8bytes; - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_PING_RESPONSE); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_PING_RESPONSE); } } } diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.h b/src/core/ext/transport/chttp2/transport/frame_ping.h index 75bacfb1d4..76ca397709 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.h +++ b/src/core/ext/transport/chttp2/transport/frame_ping.h @@ -33,7 +33,7 @@ grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint64_t opaque_8bytes); grpc_error* grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser* parser, uint32_t length, uint8_t flags); -grpc_error* grpc_chttp2_ping_parser_parse(void* parser, +grpc_error* grpc_chttp2_ping_parser_parse(grpc_exec_ctx* exec_ctx, void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last); diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc index fee576678d..05a7f056a4 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc @@ -69,7 +69,8 @@ grpc_error* grpc_chttp2_rst_stream_parser_begin_frame( return GRPC_ERROR_NONE; } -grpc_error* grpc_chttp2_rst_stream_parser_parse(void* parser, +grpc_error* grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx* exec_ctx, + void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last) { @@ -102,7 +103,7 @@ grpc_error* grpc_chttp2_rst_stream_parser_parse(void* parser, GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason); gpr_free(message); } - grpc_chttp2_mark_stream_closed(t, s, true, true, error); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, true, error); } return GRPC_ERROR_NONE; diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h index e76a3ca841..7dfc5d4578 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h @@ -34,7 +34,8 @@ grpc_slice grpc_chttp2_rst_stream_create(uint32_t stream_id, uint32_t code, grpc_error* grpc_chttp2_rst_stream_parser_begin_frame( grpc_chttp2_rst_stream_parser* parser, uint32_t length, uint8_t flags); -grpc_error* grpc_chttp2_rst_stream_parser_parse(void* parser, +grpc_error* grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx* exec_ctx, + void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last); diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.cc b/src/core/ext/transport/chttp2/transport/frame_settings.cc index c6c2a6c301..de4340fea5 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.cc +++ b/src/core/ext/transport/chttp2/transport/frame_settings.cc @@ -108,7 +108,8 @@ grpc_error* grpc_chttp2_settings_parser_begin_frame( } } -grpc_error* grpc_chttp2_settings_parser_parse(void* p, grpc_chttp2_transport* t, +grpc_error* grpc_chttp2_settings_parser_parse(grpc_exec_ctx* exec_ctx, void* p, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last) { grpc_chttp2_settings_parser* parser = (grpc_chttp2_settings_parser*)p; @@ -131,7 +132,7 @@ grpc_error* grpc_chttp2_settings_parser_parse(void* p, grpc_chttp2_transport* t, GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); grpc_slice_buffer_add(&t->qbuf, grpc_chttp2_settings_ack_create()); if (t->notify_on_receive_settings != nullptr) { - GRPC_CLOSURE_SCHED(t->notify_on_receive_settings, + GRPC_CLOSURE_SCHED(exec_ctx, t->notify_on_receive_settings, GRPC_ERROR_NONE); t->notify_on_receive_settings = nullptr; } diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.h b/src/core/ext/transport/chttp2/transport/frame_settings.h index ce65402815..36e2ca83a0 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.h +++ b/src/core/ext/transport/chttp2/transport/frame_settings.h @@ -52,7 +52,8 @@ grpc_slice grpc_chttp2_settings_ack_create(void); grpc_error* grpc_chttp2_settings_parser_begin_frame( grpc_chttp2_settings_parser* parser, uint32_t length, uint8_t flags, uint32_t* settings); -grpc_error* grpc_chttp2_settings_parser_parse(void* parser, +grpc_error* grpc_chttp2_settings_parser_parse(grpc_exec_ctx* exec_ctx, + void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last); diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.cc b/src/core/ext/transport/chttp2/transport/frame_window_update.cc index 418ca144ce..08407a8e67 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.cc +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.cc @@ -64,11 +64,9 @@ grpc_error* grpc_chttp2_window_update_parser_begin_frame( return GRPC_ERROR_NONE; } -grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, - grpc_chttp2_transport* t, - grpc_chttp2_stream* s, - grpc_slice slice, - int is_last) { +grpc_error* grpc_chttp2_window_update_parser_parse( + grpc_exec_ctx* exec_ctx, void* parser, grpc_chttp2_transport* t, + grpc_chttp2_stream* s, grpc_slice slice, int is_last) { uint8_t* const beg = GRPC_SLICE_START_PTR(slice); uint8_t* const end = GRPC_SLICE_END_PTR(slice); uint8_t* cur = beg; @@ -100,9 +98,10 @@ grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, if (s != nullptr) { s->flow_control->RecvUpdate(received_update); if (grpc_chttp2_list_remove_stalled_by_stream(t, s)) { - grpc_chttp2_mark_stream_writable(t, s); + grpc_chttp2_mark_stream_writable(exec_ctx, t, s); grpc_chttp2_initiate_write( - t, GRPC_CHTTP2_INITIATE_WRITE_FLOW_CONTROL_UNSTALLED_BY_UPDATE); + exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_FLOW_CONTROL_UNSTALLED_BY_UPDATE); } } } else { @@ -111,7 +110,8 @@ grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, bool is_zero = t->flow_control->remote_window() <= 0; if (was_zero && !is_zero) { grpc_chttp2_initiate_write( - t, GRPC_CHTTP2_INITIATE_WRITE_TRANSPORT_FLOW_CONTROL_UNSTALLED); + exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_TRANSPORT_FLOW_CONTROL_UNSTALLED); } } } diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.h b/src/core/ext/transport/chttp2/transport/frame_window_update.h index a32f1a9d11..e031b585fa 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.h +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.h @@ -35,10 +35,8 @@ grpc_slice grpc_chttp2_window_update_create( grpc_error* grpc_chttp2_window_update_parser_begin_frame( grpc_chttp2_window_update_parser* parser, uint32_t length, uint8_t flags); -grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, - grpc_chttp2_transport* t, - grpc_chttp2_stream* s, - grpc_slice slice, - int is_last); +grpc_error* grpc_chttp2_window_update_parser_parse( + grpc_exec_ctx* exec_ctx, void* parser, grpc_chttp2_transport* t, + grpc_chttp2_stream* s, grpc_slice slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_WINDOW_UPDATE_H */ diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 3a5692a694..e76d92e31d 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -206,12 +206,14 @@ static uint32_t prepare_space_for_new_elem(grpc_chttp2_hpack_compressor* c, } /* dummy function */ -static void add_nothing(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, +static void add_nothing(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, size_t elem_size) {} // Add a key to the dynamic table. Both key and value will be added to table at // the decoder. -static void add_key_with_index(grpc_chttp2_hpack_compressor* c, +static void add_key_with_index(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, uint32_t new_index) { if (new_index == 0) { return; @@ -238,12 +240,14 @@ static void add_key_with_index(grpc_chttp2_hpack_compressor* c, c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; } else if (c->indices_keys[HASH_FRAGMENT_2(key_hash)] < c->indices_keys[HASH_FRAGMENT_3(key_hash)]) { - grpc_slice_unref_internal(c->entries_keys[HASH_FRAGMENT_2(key_hash)]); + grpc_slice_unref_internal(exec_ctx, + c->entries_keys[HASH_FRAGMENT_2(key_hash)]); c->entries_keys[HASH_FRAGMENT_2(key_hash)] = grpc_slice_ref_internal(GRPC_MDKEY(elem)); c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; } else { - grpc_slice_unref_internal(c->entries_keys[HASH_FRAGMENT_3(key_hash)]); + grpc_slice_unref_internal(exec_ctx, + c->entries_keys[HASH_FRAGMENT_3(key_hash)]); c->entries_keys[HASH_FRAGMENT_3(key_hash)] = grpc_slice_ref_internal(GRPC_MDKEY(elem)); c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; @@ -251,7 +255,8 @@ static void add_key_with_index(grpc_chttp2_hpack_compressor* c, } /* add an element to the decoder table */ -static void add_elem_with_index(grpc_chttp2_hpack_compressor* c, +static void add_elem_with_index(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, uint32_t new_index) { if (new_index == 0) { return; @@ -281,34 +286,35 @@ static void add_elem_with_index(grpc_chttp2_hpack_compressor* c, } else if (c->indices_elems[HASH_FRAGMENT_2(elem_hash)] < c->indices_elems[HASH_FRAGMENT_3(elem_hash)]) { /* not there: replace oldest */ - GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_2(elem_hash)]); + GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_2(elem_hash)]); c->entries_elems[HASH_FRAGMENT_2(elem_hash)] = GRPC_MDELEM_REF(elem); c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; } else { /* not there: replace oldest */ - GRPC_MDELEM_UNREF(c->entries_elems[HASH_FRAGMENT_3(elem_hash)]); + GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[HASH_FRAGMENT_3(elem_hash)]); c->entries_elems[HASH_FRAGMENT_3(elem_hash)] = GRPC_MDELEM_REF(elem); c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index; } - add_key_with_index(c, elem, new_index); + add_key_with_index(exec_ctx, c, elem, new_index); } -static void add_elem(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, - size_t elem_size) { +static void add_elem(grpc_exec_ctx* exec_ctx, grpc_chttp2_hpack_compressor* c, + grpc_mdelem elem, size_t elem_size) { uint32_t new_index = prepare_space_for_new_elem(c, elem_size); - add_elem_with_index(c, elem, new_index); + add_elem_with_index(exec_ctx, c, elem, new_index); } -static void add_key(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, - size_t elem_size) { +static void add_key(grpc_exec_ctx* exec_ctx, grpc_chttp2_hpack_compressor* c, + grpc_mdelem elem, size_t elem_size) { uint32_t new_index = prepare_space_for_new_elem(c, elem_size); - add_key_with_index(c, elem, new_index); + add_key_with_index(exec_ctx, c, elem, new_index); } -static void emit_indexed(grpc_chttp2_hpack_compressor* c, uint32_t elem_index, +static void emit_indexed(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, uint32_t elem_index, framer_state* st) { - GRPC_STATS_INC_HPACK_SEND_INDEXED(); + GRPC_STATS_INC_HPACK_SEND_INDEXED(exec_ctx); uint32_t len = GRPC_CHTTP2_VARINT_LENGTH(elem_index, 1); GRPC_CHTTP2_WRITE_VARINT(elem_index, 1, 0x80, add_tiny_header_data(st, len), len); @@ -320,17 +326,18 @@ typedef struct { bool insert_null_before_wire_value; } wire_value; -static wire_value get_wire_value(grpc_mdelem elem, bool true_binary_enabled) { +static wire_value get_wire_value(grpc_exec_ctx* exec_ctx, grpc_mdelem elem, + bool true_binary_enabled) { wire_value wire_val; if (grpc_is_binary_header(GRPC_MDKEY(elem))) { if (true_binary_enabled) { - GRPC_STATS_INC_HPACK_SEND_BINARY(); + GRPC_STATS_INC_HPACK_SEND_BINARY(exec_ctx); wire_val.huffman_prefix = 0x00; wire_val.insert_null_before_wire_value = true; wire_val.data = grpc_slice_ref_internal(GRPC_MDVALUE(elem)); } else { - GRPC_STATS_INC_HPACK_SEND_BINARY_BASE64(); + GRPC_STATS_INC_HPACK_SEND_BINARY_BASE64(exec_ctx); wire_val.huffman_prefix = 0x80; wire_val.insert_null_before_wire_value = false; wire_val.data = @@ -338,7 +345,7 @@ static wire_value get_wire_value(grpc_mdelem elem, bool true_binary_enabled) { } } else { /* TODO(ctiller): opportunistically compress non-binary headers */ - GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(); + GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(exec_ctx); wire_val.huffman_prefix = 0x00; wire_val.insert_null_before_wire_value = false; wire_val.data = grpc_slice_ref_internal(GRPC_MDVALUE(elem)); @@ -355,12 +362,14 @@ static void add_wire_value(framer_state* st, wire_value v) { add_header_data(st, v.data); } -static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor* c, +static void emit_lithdr_incidx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, uint32_t key_index, grpc_mdelem elem, framer_state* st) { - GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX(); + GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX(exec_ctx); uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 2); - wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + wire_value value = + get_wire_value(exec_ctx, elem, st->use_true_binary_metadata); size_t len_val = wire_value_length(value); uint32_t len_val_len; GPR_ASSERT(len_val <= UINT32_MAX); @@ -372,12 +381,14 @@ static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor* c, add_wire_value(st, value); } -static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor* c, +static void emit_lithdr_noidx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, uint32_t key_index, grpc_mdelem elem, framer_state* st) { - GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX(); + GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX(exec_ctx); uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 4); - wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + wire_value value = + get_wire_value(exec_ctx, elem, st->use_true_binary_metadata); size_t len_val = wire_value_length(value); uint32_t len_val_len; GPR_ASSERT(len_val <= UINT32_MAX); @@ -389,14 +400,16 @@ static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor* c, add_wire_value(st, value); } -static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor* c, +static void emit_lithdr_incidx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, uint32_t unused_index, grpc_mdelem elem, framer_state* st) { GPR_ASSERT(unused_index == 0); - GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V(); - GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(); + GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V(exec_ctx); + GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(exec_ctx); uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); - wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + wire_value value = + get_wire_value(exec_ctx, elem, st->use_true_binary_metadata); uint32_t len_val = (uint32_t)wire_value_length(value); uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); @@ -411,14 +424,16 @@ static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor* c, add_wire_value(st, value); } -static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor* c, +static void emit_lithdr_noidx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, uint32_t unused_index, grpc_mdelem elem, framer_state* st) { GPR_ASSERT(unused_index == 0); - GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V(); - GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(); + GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V(exec_ctx); + GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(exec_ctx); uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); - wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + wire_value value = + get_wire_value(exec_ctx, elem, st->use_true_binary_metadata); uint32_t len_val = (uint32_t)wire_value_length(value); uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); @@ -447,8 +462,8 @@ static uint32_t dynidx(grpc_chttp2_hpack_compressor* c, uint32_t elem_index) { } /* encode an mdelem */ -static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, - framer_state* st) { +static void hpack_enc(grpc_exec_ctx* exec_ctx, grpc_chttp2_hpack_compressor* c, + grpc_mdelem elem, framer_state* st) { GPR_ASSERT(GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)) > 0); if (GRPC_SLICE_START_PTR(GRPC_MDKEY(elem))[0] != ':') { /* regular header */ st->seen_regular_header = 1; @@ -481,7 +496,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, // Key is not interned, emit literals. if (!key_interned) { - emit_lithdr_noidx_v(c, 0, elem, st); + emit_lithdr_noidx_v(exec_ctx, c, 0, elem, st); return; } @@ -500,16 +515,16 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem) && c->indices_elems[HASH_FRAGMENT_2(elem_hash)] > c->tail_remote_index) { /* HIT: complete element (first cuckoo hash) */ - emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_2(elem_hash)]), - st); + emit_indexed(exec_ctx, c, + dynidx(c, c->indices_elems[HASH_FRAGMENT_2(elem_hash)]), st); return; } if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)], elem) && c->indices_elems[HASH_FRAGMENT_3(elem_hash)] > c->tail_remote_index) { /* HIT: complete element (second cuckoo hash) */ - emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)]), - st); + emit_indexed(exec_ctx, c, + dynidx(c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)]), st); return; } } @@ -523,10 +538,10 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, decoder_space_usage < MAX_DECODER_SPACE_USAGE && c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >= c->filter_elems_sum / ONE_ON_ADD_PROBABILITY; - void (*maybe_add)(grpc_chttp2_hpack_compressor*, grpc_mdelem, size_t) = - should_add_elem ? add_elem : add_nothing; - void (*emit)(grpc_chttp2_hpack_compressor*, uint32_t, grpc_mdelem, - framer_state*) = + void (*maybe_add)(grpc_exec_ctx*, grpc_chttp2_hpack_compressor*, grpc_mdelem, + size_t) = should_add_elem ? add_elem : add_nothing; + void (*emit)(grpc_exec_ctx*, grpc_chttp2_hpack_compressor*, uint32_t, + grpc_mdelem, framer_state*) = should_add_elem ? emit_lithdr_incidx : emit_lithdr_noidx; /* no hits for the elem... maybe there's a key? */ @@ -535,8 +550,8 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, GRPC_MDKEY(elem)) && indices_key > c->tail_remote_index) { /* HIT: key (first cuckoo hash) */ - emit(c, dynidx(c, indices_key), elem, st); - maybe_add(c, elem, decoder_space_usage); + emit(exec_ctx, c, dynidx(c, indices_key), elem, st); + maybe_add(exec_ctx, c, elem, decoder_space_usage); return; } @@ -545,8 +560,8 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, GRPC_MDKEY(elem)) && indices_key > c->tail_remote_index) { /* HIT: key (first cuckoo hash) */ - emit(c, dynidx(c, indices_key), elem, st); - maybe_add(c, elem, decoder_space_usage); + emit(exec_ctx, c, dynidx(c, indices_key), elem, st); + maybe_add(exec_ctx, c, elem, decoder_space_usage); return; } @@ -557,23 +572,24 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, : emit_lithdr_noidx_v; maybe_add = should_add_elem ? add_elem : (should_add_key ? add_key : add_nothing); - emit(c, 0, elem, st); - maybe_add(c, elem, decoder_space_usage); + emit(exec_ctx, c, 0, elem, st); + maybe_add(exec_ctx, c, elem, decoder_space_usage); } #define STRLEN_LIT(x) (sizeof(x) - 1) #define TIMEOUT_KEY "grpc-timeout" -static void deadline_enc(grpc_chttp2_hpack_compressor* c, grpc_millis deadline, +static void deadline_enc(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, grpc_millis deadline, framer_state* st) { char timeout_str[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; grpc_mdelem mdelem; - grpc_http2_encode_timeout(deadline - grpc_core::ExecCtx::Get()->Now(), + grpc_http2_encode_timeout(deadline - grpc_exec_ctx_now(exec_ctx), timeout_str); - mdelem = grpc_mdelem_from_slices(GRPC_MDSTR_GRPC_TIMEOUT, + mdelem = grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_TIMEOUT, grpc_slice_from_copied_string(timeout_str)); - hpack_enc(c, mdelem, st); - GRPC_MDELEM_UNREF(mdelem); + hpack_enc(exec_ctx, c, mdelem, st); + GRPC_MDELEM_UNREF(exec_ctx, mdelem); } static uint32_t elems_for_bytes(uint32_t bytes) { return (bytes + 31) / 32; } @@ -593,13 +609,14 @@ void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor* c) { } } -void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor* c) { +void grpc_chttp2_hpack_compressor_destroy(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c) { int i; for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) { if (c->entries_keys[i].refcount != &terminal_slice_refcount) { - grpc_slice_unref_internal(c->entries_keys[i]); + grpc_slice_unref_internal(exec_ctx, c->entries_keys[i]); } - GRPC_MDELEM_UNREF(c->entries_elems[i]); + GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[i]); } gpr_free(c->table_elem_size); } @@ -655,7 +672,8 @@ void grpc_chttp2_hpack_compressor_set_max_table_size( } } -void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, +void grpc_chttp2_encode_header(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, grpc_mdelem** extra_headers, size_t extra_headers_size, grpc_metadata_batch* metadata, @@ -681,15 +699,15 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, emit_advertise_table_size_change(c, &st); } for (size_t i = 0; i < extra_headers_size; ++i) { - hpack_enc(c, *extra_headers[i], &st); + hpack_enc(exec_ctx, c, *extra_headers[i], &st); } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { - hpack_enc(c, l->md, &st); + hpack_enc(exec_ctx, c, l->md, &st); } grpc_millis deadline = metadata->deadline; if (deadline != GRPC_MILLIS_INF_FUTURE) { - deadline_enc(c, deadline, &st); + deadline_enc(exec_ctx, c, deadline, &st); } finish_frame(&st, 1, options->is_eof); diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h index a26514cab0..08921b19ec 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h @@ -70,7 +70,8 @@ typedef struct { } grpc_chttp2_hpack_compressor; void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor* c); -void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor* c); +void grpc_chttp2_hpack_compressor_destroy(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c); void grpc_chttp2_hpack_compressor_set_max_table_size( grpc_chttp2_hpack_compressor* c, uint32_t max_table_size); void grpc_chttp2_hpack_compressor_set_max_usable_size( @@ -84,7 +85,8 @@ typedef struct { grpc_transport_one_way_stats* stats; } grpc_encode_header_options; -void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, +void grpc_chttp2_encode_header(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_compressor* c, grpc_mdelem** extra_headers, size_t extra_headers_size, grpc_metadata_batch* metadata, diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index a395ab234c..18cb27f199 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -61,69 +61,96 @@ typedef enum { a set of indirect jumps, and so not waste stack space. */ /* forward declarations for parsing states */ -static grpc_error* parse_begin(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_begin(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_error(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_error(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end, grpc_error* error); -static grpc_error* still_parse_error(grpc_chttp2_hpack_parser* p, +static grpc_error* still_parse_error(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_illegal_op(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_illegal_op(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_string_prefix(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_string_prefix(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_key_string(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_key_string(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); static grpc_error* parse_value_string_with_indexed_key( - grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); + grpc_exec_ctx* exec_ctx, grpc_chttp2_hpack_parser* p, const uint8_t* cur, + const uint8_t* end); static grpc_error* parse_value_string_with_literal_key( - grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); + grpc_exec_ctx* exec_ctx, grpc_chttp2_hpack_parser* p, const uint8_t* cur, + const uint8_t* end); -static grpc_error* parse_value0(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value0(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_value1(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value1(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_value2(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value2(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_value3(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value3(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_value4(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value4(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_value5up(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_value5up(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_indexed_field(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_indexed_field(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_indexed_field_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_indexed_field_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_lithdr_incidx(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_incidx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_lithdr_incidx_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_incidx_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_lithdr_incidx_v(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_incidx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_lithdr_notidx(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_notidx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_lithdr_notidx_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_notidx_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_lithdr_notidx_v(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_notidx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_lithdr_nvridx(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_nvridx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_nvridx_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_nvridx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_max_tbl_size(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_max_tbl_size(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); -static grpc_error* parse_max_tbl_size_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_max_tbl_size_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end); /* we translate the first byte of a hpack field into one of these decoding @@ -622,8 +649,8 @@ static const uint8_t inverse_base64[256] = { }; /* emission helpers */ -static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md, - int add_to_table) { +static grpc_error* on_hdr(grpc_exec_ctx* exec_ctx, grpc_chttp2_hpack_parser* p, + grpc_mdelem md, int add_to_table) { if (grpc_http_trace.enabled()) { char* k = grpc_slice_to_c_string(GRPC_MDKEY(md)); char* v = nullptr; @@ -644,25 +671,26 @@ static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md, if (add_to_table) { GPR_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED || GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC); - grpc_error* err = grpc_chttp2_hptbl_add(&p->table, md); + grpc_error* err = grpc_chttp2_hptbl_add(exec_ctx, &p->table, md); if (err != GRPC_ERROR_NONE) return err; } if (p->on_header == nullptr) { - GRPC_MDELEM_UNREF(md); + GRPC_MDELEM_UNREF(exec_ctx, md); return GRPC_ERROR_CREATE_FROM_STATIC_STRING("on_header callback not set"); } - p->on_header(p->on_header_user_data, md); + p->on_header(exec_ctx, p->on_header_user_data, md); return GRPC_ERROR_NONE; } -static grpc_slice take_string(grpc_chttp2_hpack_parser* p, +static grpc_slice take_string(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, grpc_chttp2_hpack_parser_string* str, bool intern) { grpc_slice s; if (!str->copied) { if (intern) { s = grpc_slice_intern(str->data.referenced); - grpc_slice_unref_internal(str->data.referenced); + grpc_slice_unref_internal(exec_ctx, str->data.referenced); } else { s = str->data.referenced; } @@ -680,77 +708,85 @@ static grpc_slice take_string(grpc_chttp2_hpack_parser* p, } /* jump to the next state */ -static grpc_error* parse_next(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_next(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { p->state = *p->next_state++; - return p->state(p, cur, end); + return p->state(exec_ctx, p, cur, end); } /* begin parsing a header: all functionality is encoded into lookup tables above */ -static grpc_error* parse_begin(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_begin(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_begin; return GRPC_ERROR_NONE; } - return first_byte_action[first_byte_lut[*cur]](p, cur, end); + return first_byte_action[first_byte_lut[*cur]](exec_ctx, p, cur, end); } /* stream dependency and prioritization data: we just skip it */ -static grpc_error* parse_stream_weight(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_stream_weight(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_stream_weight; return GRPC_ERROR_NONE; } - return p->after_prioritization(p, cur + 1, end); + return p->after_prioritization(exec_ctx, p, cur + 1, end); } -static grpc_error* parse_stream_dep3(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_stream_dep3(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_stream_dep3; return GRPC_ERROR_NONE; } - return parse_stream_weight(p, cur + 1, end); + return parse_stream_weight(exec_ctx, p, cur + 1, end); } -static grpc_error* parse_stream_dep2(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_stream_dep2(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_stream_dep2; return GRPC_ERROR_NONE; } - return parse_stream_dep3(p, cur + 1, end); + return parse_stream_dep3(exec_ctx, p, cur + 1, end); } -static grpc_error* parse_stream_dep1(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_stream_dep1(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_stream_dep1; return GRPC_ERROR_NONE; } - return parse_stream_dep2(p, cur + 1, end); + return parse_stream_dep2(exec_ctx, p, cur + 1, end); } -static grpc_error* parse_stream_dep0(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_stream_dep0(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_stream_dep0; return GRPC_ERROR_NONE; } - return parse_stream_dep1(p, cur + 1, end); + return parse_stream_dep1(exec_ctx, p, cur + 1, end); } /* emit an indexed field; jumps to begin the next field on completion */ -static grpc_error* finish_indexed_field(grpc_chttp2_hpack_parser* p, +static grpc_error* finish_indexed_field(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index); @@ -762,22 +798,24 @@ static grpc_error* finish_indexed_field(grpc_chttp2_hpack_parser* p, GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents); } GRPC_MDELEM_REF(md); - GRPC_STATS_INC_HPACK_RECV_INDEXED(); - grpc_error* err = on_hdr(p, md, 0); + GRPC_STATS_INC_HPACK_RECV_INDEXED(exec_ctx); + grpc_error* err = on_hdr(exec_ctx, p, md, 0); if (err != GRPC_ERROR_NONE) return err; - return parse_begin(p, cur, end); + return parse_begin(exec_ctx, p, cur, end); } /* parse an indexed field with index < 127 */ -static grpc_error* parse_indexed_field(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_indexed_field(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { p->dynamic_table_update_allowed = 0; p->index = (*cur) & 0x7f; - return finish_indexed_field(p, cur + 1, end); + return finish_indexed_field(exec_ctx, p, cur + 1, end); } /* parse an indexed field with index >= 127 */ -static grpc_error* parse_indexed_field_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_indexed_field_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -786,52 +824,56 @@ static grpc_error* parse_indexed_field_x(grpc_chttp2_hpack_parser* p, p->next_state = and_then; p->index = 0x7f; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* finish a literal header with incremental indexing */ -static grpc_error* finish_lithdr_incidx(grpc_chttp2_hpack_parser* p, +static grpc_error* finish_lithdr_incidx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */ - GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), - take_string(p, &p->value, true)), - 1); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX(exec_ctx); + grpc_error* err = on_hdr( + exec_ctx, p, + grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(md)), + take_string(exec_ctx, p, &p->value, true)), + 1); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* finish a literal header with incremental indexing with no index */ -static grpc_error* finish_lithdr_incidx_v(grpc_chttp2_hpack_parser* p, +static grpc_error* finish_lithdr_incidx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { - GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX_V(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(take_string(p, &p->key, true), - take_string(p, &p->value, true)), - 1); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX_V(exec_ctx); + grpc_error* err = on_hdr( + exec_ctx, p, + grpc_mdelem_from_slices(exec_ctx, take_string(exec_ctx, p, &p->key, true), + take_string(exec_ctx, p, &p->value, true)), + 1); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* parse a literal header with incremental indexing; index < 63 */ -static grpc_error* parse_lithdr_incidx(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_incidx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { parse_value_string_with_indexed_key, finish_lithdr_incidx}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = (*cur) & 0x3f; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* parse a literal header with incremental indexing; index >= 63 */ -static grpc_error* parse_lithdr_incidx_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_incidx_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -841,11 +883,12 @@ static grpc_error* parse_lithdr_incidx_x(grpc_chttp2_hpack_parser* p, p->next_state = and_then; p->index = 0x3f; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* parse a literal header with incremental indexing; index = 0 */ -static grpc_error* parse_lithdr_incidx_v(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_incidx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -853,52 +896,56 @@ static grpc_error* parse_lithdr_incidx_v(grpc_chttp2_hpack_parser* p, parse_value_string_with_literal_key, finish_lithdr_incidx_v}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* finish a literal header without incremental indexing */ -static grpc_error* finish_lithdr_notidx(grpc_chttp2_hpack_parser* p, +static grpc_error* finish_lithdr_notidx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */ - GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), - take_string(p, &p->value, false)), - 0); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX(exec_ctx); + grpc_error* err = on_hdr( + exec_ctx, p, + grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(md)), + take_string(exec_ctx, p, &p->value, false)), + 0); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* finish a literal header without incremental indexing with index = 0 */ -static grpc_error* finish_lithdr_notidx_v(grpc_chttp2_hpack_parser* p, +static grpc_error* finish_lithdr_notidx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { - GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX_V(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(take_string(p, &p->key, true), - take_string(p, &p->value, false)), - 0); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX_V(exec_ctx); + grpc_error* err = on_hdr( + exec_ctx, p, + grpc_mdelem_from_slices(exec_ctx, take_string(exec_ctx, p, &p->key, true), + take_string(exec_ctx, p, &p->value, false)), + 0); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* parse a literal header without incremental indexing; index < 15 */ -static grpc_error* parse_lithdr_notidx(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_notidx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { parse_value_string_with_indexed_key, finish_lithdr_notidx}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = (*cur) & 0xf; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* parse a literal header without incremental indexing; index >= 15 */ -static grpc_error* parse_lithdr_notidx_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_notidx_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -908,11 +955,12 @@ static grpc_error* parse_lithdr_notidx_x(grpc_chttp2_hpack_parser* p, p->next_state = and_then; p->index = 0xf; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* parse a literal header without incremental indexing; index == 0 */ -static grpc_error* parse_lithdr_notidx_v(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_notidx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -920,52 +968,56 @@ static grpc_error* parse_lithdr_notidx_v(grpc_chttp2_hpack_parser* p, parse_value_string_with_literal_key, finish_lithdr_notidx_v}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* finish a literal header that is never indexed */ -static grpc_error* finish_lithdr_nvridx(grpc_chttp2_hpack_parser* p, +static grpc_error* finish_lithdr_nvridx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */ - GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), - take_string(p, &p->value, false)), - 0); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX(exec_ctx); + grpc_error* err = on_hdr( + exec_ctx, p, + grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(md)), + take_string(exec_ctx, p, &p->value, false)), + 0); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* finish a literal header that is never indexed with an extra value */ -static grpc_error* finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p, +static grpc_error* finish_lithdr_nvridx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { - GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX_V(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(take_string(p, &p->key, true), - take_string(p, &p->value, false)), - 0); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX_V(exec_ctx); + grpc_error* err = on_hdr( + exec_ctx, p, + grpc_mdelem_from_slices(exec_ctx, take_string(exec_ctx, p, &p->key, true), + take_string(exec_ctx, p, &p->value, false)), + 0); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* parse a literal header that is never indexed; index < 15 */ -static grpc_error* parse_lithdr_nvridx(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_nvridx(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { parse_value_string_with_indexed_key, finish_lithdr_nvridx}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = (*cur) & 0xf; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* parse a literal header that is never indexed; index >= 15 */ -static grpc_error* parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_nvridx_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -975,11 +1027,12 @@ static grpc_error* parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser* p, p->next_state = and_then; p->index = 0xf; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* parse a literal header that is never indexed; index == 0 */ -static grpc_error* parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_lithdr_nvridx_v(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { @@ -987,44 +1040,47 @@ static grpc_error* parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p, parse_value_string_with_literal_key, finish_lithdr_nvridx_v}; p->dynamic_table_update_allowed = 0; p->next_state = and_then; - return parse_string_prefix(p, cur + 1, end); + return parse_string_prefix(exec_ctx, p, cur + 1, end); } /* finish parsing a max table size change */ -static grpc_error* finish_max_tbl_size(grpc_chttp2_hpack_parser* p, +static grpc_error* finish_max_tbl_size(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (grpc_http_trace.enabled()) { gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index); } grpc_error* err = - grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_begin(p, cur, end); + grpc_chttp2_hptbl_set_current_table_size(exec_ctx, &p->table, p->index); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_begin(exec_ctx, p, cur, end); } /* parse a max table size change, max size < 15 */ -static grpc_error* parse_max_tbl_size(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_max_tbl_size(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (p->dynamic_table_update_allowed == 0) { return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "More than two max table size changes in a single frame")); } p->dynamic_table_update_allowed--; p->index = (*cur) & 0x1f; - return finish_max_tbl_size(p, cur + 1, end); + return finish_max_tbl_size(exec_ctx, p, cur + 1, end); } /* parse a max table size change, max size >= 15 */ -static grpc_error* parse_max_tbl_size_x(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_max_tbl_size_x(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { static const grpc_chttp2_hpack_parser_state and_then[] = { finish_max_tbl_size}; if (p->dynamic_table_update_allowed == 0) { return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "More than two max table size changes in a single frame")); } @@ -1032,11 +1088,12 @@ static grpc_error* parse_max_tbl_size_x(grpc_chttp2_hpack_parser* p, p->next_state = and_then; p->index = 0x1f; p->parsing.value = &p->index; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } /* a parse error: jam the parse state into parse_error, and return error */ -static grpc_error* parse_error(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_error(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end, grpc_error* err) { GPR_ASSERT(err != GRPC_ERROR_NONE); if (p->last_error == GRPC_ERROR_NONE) { @@ -1046,24 +1103,27 @@ static grpc_error* parse_error(grpc_chttp2_hpack_parser* p, const uint8_t* cur, return err; } -static grpc_error* still_parse_error(grpc_chttp2_hpack_parser* p, +static grpc_error* still_parse_error(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { return GRPC_ERROR_REF(p->last_error); } -static grpc_error* parse_illegal_op(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_illegal_op(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { GPR_ASSERT(cur != end); char* msg; gpr_asprintf(&msg, "Illegal hpack op code %d", *cur); grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } /* parse the 1st byte of a varint into p->parsing.value no overflow is possible */ -static grpc_error* parse_value0(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value0(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_value0; @@ -1073,15 +1133,16 @@ static grpc_error* parse_value0(grpc_chttp2_hpack_parser* p, const uint8_t* cur, *p->parsing.value += (*cur) & 0x7f; if ((*cur) & 0x80) { - return parse_value1(p, cur + 1, end); + return parse_value1(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } /* parse the 2nd byte of a varint into p->parsing.value no overflow is possible */ -static grpc_error* parse_value1(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value1(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_value1; @@ -1091,15 +1152,16 @@ static grpc_error* parse_value1(grpc_chttp2_hpack_parser* p, const uint8_t* cur, *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 7; if ((*cur) & 0x80) { - return parse_value2(p, cur + 1, end); + return parse_value2(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } /* parse the 3rd byte of a varint into p->parsing.value no overflow is possible */ -static grpc_error* parse_value2(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value2(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_value2; @@ -1109,15 +1171,16 @@ static grpc_error* parse_value2(grpc_chttp2_hpack_parser* p, const uint8_t* cur, *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 14; if ((*cur) & 0x80) { - return parse_value3(p, cur + 1, end); + return parse_value3(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } /* parse the 4th byte of a varint into p->parsing.value no overflow is possible */ -static grpc_error* parse_value3(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value3(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_value3; @@ -1127,15 +1190,16 @@ static grpc_error* parse_value3(grpc_chttp2_hpack_parser* p, const uint8_t* cur, *p->parsing.value += (((uint32_t)*cur) & 0x7f) << 21; if ((*cur) & 0x80) { - return parse_value4(p, cur + 1, end); + return parse_value4(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } /* parse the 5th byte of a varint into p->parsing.value depending on the byte, we may overflow, and care must be taken */ -static grpc_error* parse_value4(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_value4(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { uint8_t c; uint32_t cur_value; @@ -1161,9 +1225,9 @@ static grpc_error* parse_value4(grpc_chttp2_hpack_parser* p, const uint8_t* cur, *p->parsing.value = cur_value + add_value; if ((*cur) & 0x80) { - return parse_value5up(p, cur + 1, end); + return parse_value5up(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } error: @@ -1173,13 +1237,14 @@ error: *p->parsing.value, *cur); grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } /* parse any trailing bytes in a varint: it's possible to append an arbitrary number of 0x80's and not affect the value - a zero will terminate - and anything else will overflow */ -static grpc_error* parse_value5up(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_value5up(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { while (cur != end && *cur == 0x80) { ++cur; @@ -1191,7 +1256,7 @@ static grpc_error* parse_value5up(grpc_chttp2_hpack_parser* p, } if (*cur == 0) { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } char* msg; @@ -1201,11 +1266,12 @@ static grpc_error* parse_value5up(grpc_chttp2_hpack_parser* p, *p->parsing.value, *cur); grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } /* parse a string prefix */ -static grpc_error* parse_string_prefix(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_string_prefix(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (cur == end) { p->state = parse_string_prefix; @@ -1216,9 +1282,9 @@ static grpc_error* parse_string_prefix(grpc_chttp2_hpack_parser* p, p->huff = (*cur) >> 7; if (p->strlen == 0x7f) { p->parsing.value = &p->strlen; - return parse_value0(p, cur + 1, end); + return parse_value0(exec_ctx, p, cur + 1, end); } else { - return parse_next(p, cur + 1, end); + return parse_next(exec_ctx, p, cur + 1, end); } } @@ -1237,7 +1303,8 @@ static void append_bytes(grpc_chttp2_hpack_parser_string* str, str->data.copied.length += (uint32_t)length; } -static grpc_error* append_string(grpc_chttp2_hpack_parser* p, +static grpc_error* append_string(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { grpc_chttp2_hpack_parser_string* str = p->parsing.str; uint32_t bits; @@ -1255,11 +1322,11 @@ static grpc_error* append_string(grpc_chttp2_hpack_parser* p, /* 'true-binary' case */ ++cur; p->binary = NOT_BINARY; - GRPC_STATS_INC_HPACK_RECV_BINARY(); + GRPC_STATS_INC_HPACK_RECV_BINARY(exec_ctx); append_bytes(str, cur, (size_t)(end - cur)); return GRPC_ERROR_NONE; } - GRPC_STATS_INC_HPACK_RECV_BINARY_BASE64(); + GRPC_STATS_INC_HPACK_RECV_BINARY_BASE64(exec_ctx); /* fallthrough */ b64_byte0: case B64_BYTE0: @@ -1271,7 +1338,7 @@ static grpc_error* append_string(grpc_chttp2_hpack_parser* p, ++cur; if (bits == 255) return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character")); else if (bits == 64) goto b64_byte0; @@ -1287,7 +1354,7 @@ static grpc_error* append_string(grpc_chttp2_hpack_parser* p, ++cur; if (bits == 255) return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character")); else if (bits == 64) goto b64_byte1; @@ -1303,7 +1370,7 @@ static grpc_error* append_string(grpc_chttp2_hpack_parser* p, ++cur; if (bits == 255) return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character")); else if (bits == 64) goto b64_byte2; @@ -1319,7 +1386,7 @@ static grpc_error* append_string(grpc_chttp2_hpack_parser* p, ++cur; if (bits == 255) return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal base64 character")); else if (bits == 64) goto b64_byte3; @@ -1332,11 +1399,12 @@ static grpc_error* append_string(grpc_chttp2_hpack_parser* p, goto b64_byte0; } GPR_UNREACHABLE_CODE(return parse_error( - p, cur, end, + exec_ctx, p, cur, end, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Should never reach here"))); } -static grpc_error* finish_str(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* finish_str(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { uint8_t decoded[2]; uint32_t bits; @@ -1349,7 +1417,7 @@ static grpc_error* finish_str(grpc_chttp2_hpack_parser* p, const uint8_t* cur, case B64_BYTE0: break; case B64_BYTE1: - return parse_error(p, cur, end, + return parse_error(exec_ctx, p, cur, end, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "illegal base64 encoding")); /* illegal encoding */ case B64_BYTE2: @@ -1360,7 +1428,7 @@ static grpc_error* finish_str(grpc_chttp2_hpack_parser* p, const uint8_t* cur, bits & 0xffff); grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } decoded[0] = (uint8_t)(bits >> 16); append_bytes(str, decoded, 1); @@ -1373,7 +1441,7 @@ static grpc_error* finish_str(grpc_chttp2_hpack_parser* p, const uint8_t* cur, bits & 0xff); grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); - return parse_error(p, cur, end, err); + return parse_error(exec_ctx, p, cur, end, err); } decoded[0] = (uint8_t)(bits >> 16); decoded[1] = (uint8_t)(bits >> 8); @@ -1384,13 +1452,14 @@ static grpc_error* finish_str(grpc_chttp2_hpack_parser* p, const uint8_t* cur, } /* decode a nibble from a huffman encoded stream */ -static grpc_error* huff_nibble(grpc_chttp2_hpack_parser* p, uint8_t nibble) { +static grpc_error* huff_nibble(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, uint8_t nibble) { int16_t emit = emit_sub_tbl[16 * emit_tbl[p->huff_state] + nibble]; int16_t next = next_sub_tbl[16 * next_tbl[p->huff_state] + nibble]; if (emit != -1) { if (emit >= 0 && emit < 256) { uint8_t c = (uint8_t)emit; - grpc_error* err = append_string(p, &c, (&c) + 1); + grpc_error* err = append_string(exec_ctx, p, &c, (&c) + 1); if (err != GRPC_ERROR_NONE) return err; } else { assert(emit == 256); @@ -1401,42 +1470,45 @@ static grpc_error* huff_nibble(grpc_chttp2_hpack_parser* p, uint8_t nibble) { } /* decode full bytes from a huffman encoded stream */ -static grpc_error* add_huff_bytes(grpc_chttp2_hpack_parser* p, +static grpc_error* add_huff_bytes(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { for (; cur != end; ++cur) { - grpc_error* err = huff_nibble(p, *cur >> 4); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - err = huff_nibble(p, *cur & 0xf); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); + grpc_error* err = huff_nibble(exec_ctx, p, *cur >> 4); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + err = huff_nibble(exec_ctx, p, *cur & 0xf); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); } return GRPC_ERROR_NONE; } /* decode some string bytes based on the current decoding mode (huffman or not) */ -static grpc_error* add_str_bytes(grpc_chttp2_hpack_parser* p, +static grpc_error* add_str_bytes(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { if (p->huff) { - return add_huff_bytes(p, cur, end); + return add_huff_bytes(exec_ctx, p, cur, end); } else { - return append_string(p, cur, end); + return append_string(exec_ctx, p, cur, end); } } /* parse a string - tries to do large chunks at a time */ -static grpc_error* parse_string(grpc_chttp2_hpack_parser* p, const uint8_t* cur, +static grpc_error* parse_string(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { size_t remaining = p->strlen - p->strgot; size_t given = (size_t)(end - cur); if (remaining <= given) { - grpc_error* err = add_str_bytes(p, cur, cur + remaining); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - err = finish_str(p, cur + remaining, end); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_next(p, cur + remaining, end); + grpc_error* err = add_str_bytes(exec_ctx, p, cur, cur + remaining); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + err = finish_str(exec_ctx, p, cur + remaining, end); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_next(exec_ctx, p, cur + remaining, end); } else { - grpc_error* err = add_str_bytes(p, cur, cur + given); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); + grpc_error* err = add_str_bytes(exec_ctx, p, cur, cur + given); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); GPR_ASSERT(given <= UINT32_MAX - p->strgot); p->strgot += (uint32_t)given; p->state = parse_string; @@ -1445,19 +1517,20 @@ static grpc_error* parse_string(grpc_chttp2_hpack_parser* p, const uint8_t* cur, } /* begin parsing a string - performs setup, calls parse_string */ -static grpc_error* begin_parse_string(grpc_chttp2_hpack_parser* p, +static grpc_error* begin_parse_string(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end, uint8_t binary, grpc_chttp2_hpack_parser_string* str) { if (!p->huff && binary == NOT_BINARY && (end - cur) >= (intptr_t)p->strlen && p->current_slice_refcount != nullptr) { - GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED(); + GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED(exec_ctx); str->copied = false; str->data.referenced.refcount = p->current_slice_refcount; str->data.referenced.data.refcounted.bytes = (uint8_t*)cur; str->data.referenced.data.refcounted.length = p->strlen; grpc_slice_ref_internal(str->data.referenced); - return parse_next(p, cur + p->strlen, end); + return parse_next(exec_ctx, p, cur + p->strlen, end); } p->strgot = 0; str->copied = true; @@ -1468,9 +1541,9 @@ static grpc_error* begin_parse_string(grpc_chttp2_hpack_parser* p, switch (p->binary) { case NOT_BINARY: if (p->huff) { - GRPC_STATS_INC_HPACK_RECV_HUFFMAN(); + GRPC_STATS_INC_HPACK_RECV_HUFFMAN(exec_ctx); } else { - GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED(); + GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED(exec_ctx); } break; case BINARY_BEGIN: @@ -1479,13 +1552,14 @@ static grpc_error* begin_parse_string(grpc_chttp2_hpack_parser* p, default: abort(); } - return parse_string(p, cur, end); + return parse_string(exec_ctx, p, cur, end); } /* parse the key string */ -static grpc_error* parse_key_string(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_key_string(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { - return begin_parse_string(p, cur, end, NOT_BINARY, &p->key); + return begin_parse_string(exec_ctx, p, cur, end, NOT_BINARY, &p->key); } /* check if a key represents a binary header or not */ @@ -1512,29 +1586,33 @@ static grpc_error* is_binary_indexed_header(grpc_chttp2_hpack_parser* p, } /* parse the value string */ -static grpc_error* parse_value_string(grpc_chttp2_hpack_parser* p, +static grpc_error* parse_value_string(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end, bool is_binary) { - return begin_parse_string(p, cur, end, is_binary ? BINARY_BEGIN : NOT_BINARY, - &p->value); + return begin_parse_string(exec_ctx, p, cur, end, + is_binary ? BINARY_BEGIN : NOT_BINARY, &p->value); } static grpc_error* parse_value_string_with_indexed_key( - grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { + grpc_exec_ctx* exec_ctx, grpc_chttp2_hpack_parser* p, const uint8_t* cur, + const uint8_t* end) { bool is_binary = false; grpc_error* err = is_binary_indexed_header(p, &is_binary); - if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); - return parse_value_string(p, cur, end, is_binary); + if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); + return parse_value_string(exec_ctx, p, cur, end, is_binary); } static grpc_error* parse_value_string_with_literal_key( - grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { - return parse_value_string(p, cur, end, is_binary_literal_header(p)); + grpc_exec_ctx* exec_ctx, grpc_chttp2_hpack_parser* p, const uint8_t* cur, + const uint8_t* end) { + return parse_value_string(exec_ctx, p, cur, end, is_binary_literal_header(p)); } /* PUBLIC INTERFACE */ -void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser* p) { +void grpc_chttp2_hpack_parser_init(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p) { p->on_header = nullptr; p->on_header_user_data = nullptr; p->state = parse_begin; @@ -1548,7 +1626,7 @@ void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser* p) { p->value.data.copied.length = 0; p->dynamic_table_update_allowed = 2; p->last_error = GRPC_ERROR_NONE; - grpc_chttp2_hptbl_init(&p->table); + grpc_chttp2_hptbl_init(exec_ctx, &p->table); } void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser* p) { @@ -1556,16 +1634,18 @@ void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser* p) { p->state = parse_stream_dep0; } -void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser* p) { - grpc_chttp2_hptbl_destroy(&p->table); +void grpc_chttp2_hpack_parser_destroy(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p) { + grpc_chttp2_hptbl_destroy(exec_ctx, &p->table); GRPC_ERROR_UNREF(p->last_error); - grpc_slice_unref_internal(p->key.data.referenced); - grpc_slice_unref_internal(p->value.data.referenced); + grpc_slice_unref_internal(exec_ctx, p->key.data.referenced); + grpc_slice_unref_internal(exec_ctx, p->value.data.referenced); gpr_free(p->key.data.copied.str); gpr_free(p->value.data.copied.str); } -grpc_error* grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser* p, +grpc_error* grpc_chttp2_hpack_parser_parse(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, grpc_slice slice) { /* max number of bytes to parse at a time... limits call stack depth on * compilers without TCO */ @@ -1576,33 +1656,37 @@ grpc_error* grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser* p, grpc_error* error = GRPC_ERROR_NONE; while (start != end && error == GRPC_ERROR_NONE) { uint8_t* target = start + GPR_MIN(MAX_PARSE_LENGTH, end - start); - error = p->state(p, start, target); + error = p->state(exec_ctx, p, start, target); start = target; } p->current_slice_refcount = nullptr; return error; } -typedef void (*maybe_complete_func_type)(grpc_chttp2_transport* t, +typedef void (*maybe_complete_func_type)(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s); static const maybe_complete_func_type maybe_complete_funcs[] = { grpc_chttp2_maybe_complete_recv_initial_metadata, grpc_chttp2_maybe_complete_recv_trailing_metadata}; -static void force_client_rst_stream(void* sp, grpc_error* error) { +static void force_client_rst_stream(grpc_exec_ctx* exec_ctx, void* sp, + grpc_error* error) { grpc_chttp2_stream* s = (grpc_chttp2_stream*)sp; grpc_chttp2_transport* t = s->t; if (!s->write_closed) { grpc_slice_buffer_add( &t->qbuf, grpc_chttp2_rst_stream_create(s->id, GRPC_HTTP2_NO_ERROR, &s->stats.outgoing)); - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_FORCE_RST_STREAM); - grpc_chttp2_mark_stream_closed(t, s, true, true, GRPC_ERROR_NONE); + grpc_chttp2_initiate_write(exec_ctx, t, + GRPC_CHTTP2_INITIATE_WRITE_FORCE_RST_STREAM); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, true, GRPC_ERROR_NONE); } - GRPC_CHTTP2_STREAM_UNREF(s, "final_rst"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "final_rst"); } -static void parse_stream_compression_md(grpc_chttp2_transport* t, +static void parse_stream_compression_md(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_metadata_batch* initial_metadata) { if (initial_metadata->idx.named.content_encoding == nullptr || @@ -1614,7 +1698,8 @@ static void parse_stream_compression_md(grpc_chttp2_transport* t, } } -grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, +grpc_error* grpc_chttp2_header_parser_parse(grpc_exec_ctx* exec_ctx, + void* hpack_parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last) { @@ -1623,7 +1708,7 @@ grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, if (s != nullptr) { s->stats.incoming.header_bytes += GRPC_SLICE_LENGTH(slice); } - grpc_error* error = grpc_chttp2_hpack_parser_parse(parser, slice); + grpc_error* error = grpc_chttp2_hpack_parser_parse(exec_ctx, parser, slice); if (error != GRPC_ERROR_NONE) { GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0); return error; @@ -1646,11 +1731,12 @@ grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, /* Process stream compression md element if it exists */ if (s->header_frames_received == 0) { /* Only acts on initial metadata */ - parse_stream_compression_md(t, s, &s->metadata_buffer[0].batch); + parse_stream_compression_md(exec_ctx, t, s, + &s->metadata_buffer[0].batch); } s->published_metadata[s->header_frames_received] = GRPC_METADATA_PUBLISHED_FROM_WIRE; - maybe_complete_funcs[s->header_frames_received](t, s); + maybe_complete_funcs[s->header_frames_received](exec_ctx, t, s); s->header_frames_received++; } if (parser->is_eof) { @@ -1661,11 +1747,13 @@ grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, and can avoid the extra write */ GRPC_CHTTP2_STREAM_REF(s, "final_rst"); GRPC_CLOSURE_SCHED( + exec_ctx, GRPC_CLOSURE_CREATE(force_client_rst_stream, s, grpc_combiner_finally_scheduler(t->combiner)), GRPC_ERROR_NONE); } - grpc_chttp2_mark_stream_closed(t, s, true, false, GRPC_ERROR_NONE); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, + GRPC_ERROR_NONE); } } parser->on_header = nullptr; diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h index 060bc5ce9d..b4a2b14bdb 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.h +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h @@ -30,7 +30,8 @@ typedef struct grpc_chttp2_hpack_parser grpc_chttp2_hpack_parser; typedef grpc_error* (*grpc_chttp2_hpack_parser_state)( - grpc_chttp2_hpack_parser* p, const uint8_t* beg, const uint8_t* end); + grpc_exec_ctx* exec_ctx, grpc_chttp2_hpack_parser* p, const uint8_t* beg, + const uint8_t* end); typedef struct { bool copied; @@ -46,7 +47,7 @@ typedef struct { struct grpc_chttp2_hpack_parser { /* user specified callback for each header output */ - void (*on_header)(void* user_data, grpc_mdelem md); + void (*on_header)(grpc_exec_ctx* exec_ctx, void* user_data, grpc_mdelem md); void* on_header_user_data; grpc_error* last_error; @@ -91,17 +92,21 @@ struct grpc_chttp2_hpack_parser { grpc_chttp2_hptbl table; }; -void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser* p); -void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser* p); +void grpc_chttp2_hpack_parser_init(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p); +void grpc_chttp2_hpack_parser_destroy(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p); void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser* p); -grpc_error* grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser* p, +grpc_error* grpc_chttp2_hpack_parser_parse(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hpack_parser* p, grpc_slice slice); /* wraps grpc_chttp2_hpack_parser_parse to provide a frame level parser for the transport */ -grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, +grpc_error* grpc_chttp2_header_parser_parse(grpc_exec_ctx* exec_ctx, + void* hpack_parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_slice slice, int is_last); diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc index c325465daa..75b83b80b6 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc @@ -165,7 +165,7 @@ static uint32_t entries_for_bytes(uint32_t bytes) { GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; } -void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl) { +void grpc_chttp2_hptbl_init(grpc_exec_ctx* exec_ctx, grpc_chttp2_hptbl* tbl) { size_t i; memset(tbl, 0, sizeof(*tbl)); @@ -177,19 +177,22 @@ void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl) { memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries); for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { tbl->static_ents[i - 1] = grpc_mdelem_from_slices( + exec_ctx, grpc_slice_intern(grpc_slice_from_static_string(static_table[i].key)), grpc_slice_intern( grpc_slice_from_static_string(static_table[i].value))); } } -void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl* tbl) { +void grpc_chttp2_hptbl_destroy(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hptbl* tbl) { size_t i; for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { - GRPC_MDELEM_UNREF(tbl->static_ents[i]); + GRPC_MDELEM_UNREF(exec_ctx, tbl->static_ents[i]); } for (i = 0; i < tbl->num_ents; i++) { - GRPC_MDELEM_UNREF(tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]); + GRPC_MDELEM_UNREF(exec_ctx, + tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]); } gpr_free(tbl->ents); } @@ -212,7 +215,7 @@ grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl, } /* Evict one element from the table */ -static void evict1(grpc_chttp2_hptbl* tbl) { +static void evict1(grpc_exec_ctx* exec_ctx, grpc_chttp2_hptbl* tbl) { grpc_mdelem first_ent = tbl->ents[tbl->first_ent]; size_t elem_bytes = GRPC_SLICE_LENGTH(GRPC_MDKEY(first_ent)) + GRPC_SLICE_LENGTH(GRPC_MDVALUE(first_ent)) + @@ -221,7 +224,7 @@ static void evict1(grpc_chttp2_hptbl* tbl) { tbl->mem_used -= (uint32_t)elem_bytes; tbl->first_ent = ((tbl->first_ent + 1) % tbl->cap_entries); tbl->num_ents--; - GRPC_MDELEM_UNREF(first_ent); + GRPC_MDELEM_UNREF(exec_ctx, first_ent); } static void rebuild_ents(grpc_chttp2_hptbl* tbl, uint32_t new_cap) { @@ -237,7 +240,8 @@ static void rebuild_ents(grpc_chttp2_hptbl* tbl, uint32_t new_cap) { tbl->first_ent = 0; } -void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl* tbl, +void grpc_chttp2_hptbl_set_max_bytes(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hptbl* tbl, uint32_t max_bytes) { if (tbl->max_bytes == max_bytes) { return; @@ -246,12 +250,13 @@ void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl* tbl, gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes); } while (tbl->mem_used > max_bytes) { - evict1(tbl); + evict1(exec_ctx, tbl); } tbl->max_bytes = max_bytes; } -grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl, +grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hptbl* tbl, uint32_t bytes) { if (tbl->current_table_bytes == bytes) { return GRPC_ERROR_NONE; @@ -269,7 +274,7 @@ grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl, gpr_log(GPR_DEBUG, "Update hpack parser table size to %d", bytes); } while (tbl->mem_used > bytes) { - evict1(tbl); + evict1(exec_ctx, tbl); } tbl->current_table_bytes = bytes; tbl->max_entries = entries_for_bytes(bytes); @@ -284,7 +289,8 @@ grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl, return GRPC_ERROR_NONE; } -grpc_error* grpc_chttp2_hptbl_add(grpc_chttp2_hptbl* tbl, grpc_mdelem md) { +grpc_error* grpc_chttp2_hptbl_add(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hptbl* tbl, grpc_mdelem md) { /* determine how many bytes of buffer this entry represents */ size_t elem_bytes = GRPC_SLICE_LENGTH(GRPC_MDKEY(md)) + GRPC_SLICE_LENGTH(GRPC_MDVALUE(md)) + @@ -314,14 +320,14 @@ grpc_error* grpc_chttp2_hptbl_add(grpc_chttp2_hptbl* tbl, grpc_mdelem md) { * empty table. */ while (tbl->num_ents) { - evict1(tbl); + evict1(exec_ctx, tbl); } return GRPC_ERROR_NONE; } /* evict entries to ensure no overflow */ while (elem_bytes > (size_t)tbl->current_table_bytes - tbl->mem_used) { - evict1(tbl); + evict1(exec_ctx, tbl); } /* copy the finalized entry in */ diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_table.h index 189ad1c697..aed7b13f0b 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.h +++ b/src/core/ext/transport/chttp2/transport/hpack_table.h @@ -69,18 +69,21 @@ typedef struct { } grpc_chttp2_hptbl; /* initialize a hpack table */ -void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl); -void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl* tbl); -void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl* tbl, +void grpc_chttp2_hptbl_init(grpc_exec_ctx* exec_ctx, grpc_chttp2_hptbl* tbl); +void grpc_chttp2_hptbl_destroy(grpc_exec_ctx* exec_ctx, grpc_chttp2_hptbl* tbl); +void grpc_chttp2_hptbl_set_max_bytes(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hptbl* tbl, uint32_t max_bytes); -grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl, +grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hptbl* tbl, uint32_t bytes); /* lookup a table entry based on its hpack index */ grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl, uint32_t index); /* add a table entry to the index */ -grpc_error* grpc_chttp2_hptbl_add(grpc_chttp2_hptbl* tbl, +grpc_error* grpc_chttp2_hptbl_add(grpc_exec_ctx* exec_ctx, + grpc_chttp2_hptbl* tbl, grpc_mdelem md) GRPC_MUST_USE_RESULT; /* Find a key/value pair in the table... returns the index in the table of the most similar entry, or 0 if the value was not found */ diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.cc b/src/core/ext/transport/chttp2/transport/incoming_metadata.cc index ef0c9ed230..4461f8c12c 100644 --- a/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.cc @@ -33,31 +33,33 @@ void grpc_chttp2_incoming_metadata_buffer_init( } void grpc_chttp2_incoming_metadata_buffer_destroy( - grpc_chttp2_incoming_metadata_buffer* buffer) { - grpc_metadata_batch_destroy(&buffer->batch); + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_metadata_buffer* buffer) { + grpc_metadata_batch_destroy(exec_ctx, &buffer->batch); } grpc_error* grpc_chttp2_incoming_metadata_buffer_add( - grpc_chttp2_incoming_metadata_buffer* buffer, grpc_mdelem elem) { + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_metadata_buffer* buffer, + grpc_mdelem elem) { buffer->size += GRPC_MDELEM_LENGTH(elem); return grpc_metadata_batch_add_tail( - &buffer->batch, + exec_ctx, &buffer->batch, (grpc_linked_mdelem*)gpr_arena_alloc(buffer->arena, sizeof(grpc_linked_mdelem)), elem); } grpc_error* grpc_chttp2_incoming_metadata_buffer_replace_or_add( - grpc_chttp2_incoming_metadata_buffer* buffer, grpc_mdelem elem) { + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_metadata_buffer* buffer, + grpc_mdelem elem) { for (grpc_linked_mdelem* l = buffer->batch.list.head; l != nullptr; l = l->next) { if (grpc_slice_eq(GRPC_MDKEY(l->md), GRPC_MDKEY(elem))) { - GRPC_MDELEM_UNREF(l->md); + GRPC_MDELEM_UNREF(exec_ctx, l->md); l->md = elem; return GRPC_ERROR_NONE; } } - return grpc_chttp2_incoming_metadata_buffer_add(buffer, elem); + return grpc_chttp2_incoming_metadata_buffer_add(exec_ctx, buffer, elem); } void grpc_chttp2_incoming_metadata_buffer_set_deadline( @@ -66,7 +68,8 @@ void grpc_chttp2_incoming_metadata_buffer_set_deadline( } void grpc_chttp2_incoming_metadata_buffer_publish( - grpc_chttp2_incoming_metadata_buffer* buffer, grpc_metadata_batch* batch) { + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_metadata_buffer* buffer, + grpc_metadata_batch* batch) { *batch = buffer->batch; grpc_metadata_batch_init(&buffer->batch); } diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.h b/src/core/ext/transport/chttp2/transport/incoming_metadata.h index b84cd484c4..6f2b81ef6c 100644 --- a/src/core/ext/transport/chttp2/transport/incoming_metadata.h +++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.h @@ -31,15 +31,16 @@ typedef struct { void grpc_chttp2_incoming_metadata_buffer_init( grpc_chttp2_incoming_metadata_buffer* buffer, gpr_arena* arena); void grpc_chttp2_incoming_metadata_buffer_destroy( - grpc_chttp2_incoming_metadata_buffer* buffer); + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_metadata_buffer* buffer); void grpc_chttp2_incoming_metadata_buffer_publish( - grpc_chttp2_incoming_metadata_buffer* buffer, grpc_metadata_batch* batch); + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_metadata_buffer* buffer, + grpc_metadata_batch* batch); grpc_error* grpc_chttp2_incoming_metadata_buffer_add( - grpc_chttp2_incoming_metadata_buffer* buffer, + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_metadata_buffer* buffer, grpc_mdelem elem) GRPC_MUST_USE_RESULT; grpc_error* grpc_chttp2_incoming_metadata_buffer_replace_or_add( - grpc_chttp2_incoming_metadata_buffer* buffer, + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_metadata_buffer* buffer, grpc_mdelem elem) GRPC_MUST_USE_RESULT; void grpc_chttp2_incoming_metadata_buffer_set_deadline( grpc_chttp2_incoming_metadata_buffer* buffer, grpc_millis deadline); diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 932f5ba83d..f6fd6795d0 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -282,8 +282,8 @@ struct grpc_chttp2_transport { struct { /* accept stream callback */ - void (*accept_stream)(void* user_data, grpc_transport* transport, - const void* server_data); + void (*accept_stream)(grpc_exec_ctx* exec_ctx, void* user_data, + grpc_transport* transport, const void* server_data); void* accept_stream_user_data; /** connectivity tracking */ @@ -371,8 +371,9 @@ struct grpc_chttp2_transport { /* active parser */ void* parser_data; grpc_chttp2_stream* incoming_stream; - grpc_error* (*parser)(void* parser_user_data, grpc_chttp2_transport* t, - grpc_chttp2_stream* s, grpc_slice slice, int is_last); + grpc_error* (*parser)(grpc_exec_ctx* exec_ctx, void* parser_user_data, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, + grpc_slice slice, int is_last); grpc_chttp2_write_cb* write_cb_pool; @@ -570,7 +571,8 @@ struct grpc_chttp2_stream { The actual call chain is documented in the implementation of this function. */ -void grpc_chttp2_initiate_write(grpc_chttp2_transport* t, +void grpc_chttp2_initiate_write(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_initiate_write_reason reason); typedef struct { @@ -583,12 +585,14 @@ typedef struct { } grpc_chttp2_begin_write_result; grpc_chttp2_begin_write_result grpc_chttp2_begin_write( - grpc_chttp2_transport* t); -void grpc_chttp2_end_write(grpc_chttp2_transport* t, grpc_error* error); + grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t); +void grpc_chttp2_end_write(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_error* error); /** Process one slice of incoming data; return 1 if the connection is still viable after reading, or 0 if the connection should be torn down */ -grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, +grpc_error* grpc_chttp2_perform_read(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_slice slice); bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport* t, @@ -636,23 +640,27 @@ bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport* t, // Takes in a flow control action and performs all the needed operations. void grpc_chttp2_act_on_flowctl_action( - const grpc_core::chttp2::FlowControlAction& action, + grpc_exec_ctx* exec_ctx, const grpc_core::chttp2::FlowControlAction& action, grpc_chttp2_transport* t, grpc_chttp2_stream* s); /********* End of Flow Control ***************/ grpc_chttp2_stream* grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport* t, uint32_t id); -grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t, +grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, uint32_t id); -void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, +void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, uint32_t goaway_error, grpc_slice goaway_text); -void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport* t); +void grpc_chttp2_parsing_become_skip_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); -void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, +void grpc_chttp2_complete_closure_step(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_closure** pclosure, grpc_error* error, const char* desc); @@ -673,80 +681,94 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, else \ stmt -void grpc_chttp2_fake_status(grpc_chttp2_transport* t, +void grpc_chttp2_fake_status(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_chttp2_stream* stream, grpc_error* error); -void grpc_chttp2_mark_stream_closed(grpc_chttp2_transport* t, +void grpc_chttp2_mark_stream_closed(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, int close_reads, int close_writes, grpc_error* error); -void grpc_chttp2_start_writing(grpc_chttp2_transport* t); +void grpc_chttp2_start_writing(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); #ifndef NDEBUG #define GRPC_CHTTP2_STREAM_REF(stream, reason) \ grpc_chttp2_stream_ref(stream, reason) -#define GRPC_CHTTP2_STREAM_UNREF(stream, reason) \ - grpc_chttp2_stream_unref(stream, reason) +#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream, reason) \ + grpc_chttp2_stream_unref(exec_ctx, stream, reason) void grpc_chttp2_stream_ref(grpc_chttp2_stream* s, const char* reason); -void grpc_chttp2_stream_unref(grpc_chttp2_stream* s, const char* reason); +void grpc_chttp2_stream_unref(grpc_exec_ctx* exec_ctx, grpc_chttp2_stream* s, + const char* reason); #else #define GRPC_CHTTP2_STREAM_REF(stream, reason) grpc_chttp2_stream_ref(stream) -#define GRPC_CHTTP2_STREAM_UNREF(stream, reason) \ - grpc_chttp2_stream_unref(stream) +#define GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream, reason) \ + grpc_chttp2_stream_unref(exec_ctx, stream) void grpc_chttp2_stream_ref(grpc_chttp2_stream* s); -void grpc_chttp2_stream_unref(grpc_chttp2_stream* s); +void grpc_chttp2_stream_unref(grpc_exec_ctx* exec_ctx, grpc_chttp2_stream* s); #endif #ifndef NDEBUG #define GRPC_CHTTP2_REF_TRANSPORT(t, r) \ grpc_chttp2_ref_transport(t, r, __FILE__, __LINE__) -#define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) \ - grpc_chttp2_unref_transport(t, r, __FILE__, __LINE__) -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason, +#define GRPC_CHTTP2_UNREF_TRANSPORT(cl, t, r) \ + grpc_chttp2_unref_transport(cl, t, r, __FILE__, __LINE__) +void grpc_chttp2_unref_transport(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, const char* reason, const char* file, int line); void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason, const char* file, int line); #else #define GRPC_CHTTP2_REF_TRANSPORT(t, r) grpc_chttp2_ref_transport(t) -#define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) grpc_chttp2_unref_transport(t) -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t); +#define GRPC_CHTTP2_UNREF_TRANSPORT(cl, t, r) grpc_chttp2_unref_transport(cl, t) +void grpc_chttp2_unref_transport(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); void grpc_chttp2_ref_transport(grpc_chttp2_transport* t); #endif grpc_chttp2_incoming_byte_stream* grpc_chttp2_incoming_byte_stream_create( - grpc_chttp2_transport* t, grpc_chttp2_stream* s, uint32_t frame_size, - uint32_t flags); + grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_chttp2_stream* s, + uint32_t frame_size, uint32_t flags); grpc_error* grpc_chttp2_incoming_byte_stream_push( - grpc_chttp2_incoming_byte_stream* bs, grpc_slice slice, - grpc_slice* slice_out); + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_byte_stream* bs, + grpc_slice slice, grpc_slice* slice_out); grpc_error* grpc_chttp2_incoming_byte_stream_finished( - grpc_chttp2_incoming_byte_stream* bs, grpc_error* error, - bool reset_on_error); + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_byte_stream* bs, + grpc_error* error, bool reset_on_error); void grpc_chttp2_incoming_byte_stream_notify( - grpc_chttp2_incoming_byte_stream* bs, grpc_error* error); + grpc_exec_ctx* exec_ctx, grpc_chttp2_incoming_byte_stream* bs, + grpc_error* error); -void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id); +void grpc_chttp2_ack_ping(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + uint64_t id); /** Add a new ping strike to ping_recv_state.ping_strikes. If ping_recv_state.ping_strikes > ping_policy.max_ping_strikes, it sends GOAWAY with error code ENHANCE_YOUR_CALM and additional debug data resembling "too_many_pings" followed by immediately closing the connection. */ -void grpc_chttp2_add_ping_strike(grpc_chttp2_transport* t); +void grpc_chttp2_add_ping_strike(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); /** add a ref to the stream and add it to the writable list; ref will be dropped in writing.c */ -void grpc_chttp2_mark_stream_writable(grpc_chttp2_transport* t, +void grpc_chttp2_mark_stream_writable(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s); -void grpc_chttp2_cancel_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s, +void grpc_chttp2_cancel_stream(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_error* due_to_error); -void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_chttp2_transport* t, +void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s); -void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, +void grpc_chttp2_maybe_complete_recv_message(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s); -void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t, +void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s); -void grpc_chttp2_fail_pending_writes(grpc_chttp2_transport* t, +void grpc_chttp2_fail_pending_writes(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_error* error); /** Set the default keepalive configurations, must only be called at diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index a56f89cc75..46ec3fbaa6 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -31,22 +31,33 @@ #include "src/core/lib/transport/status_conversion.h" #include "src/core/lib/transport/timeout_encoding.h" -static grpc_error* init_frame_parser(grpc_chttp2_transport* t); -static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, +static grpc_error* init_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); +static grpc_error* init_header_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, int is_continuation); -static grpc_error* init_data_frame_parser(grpc_chttp2_transport* t); -static grpc_error* init_rst_stream_parser(grpc_chttp2_transport* t); -static grpc_error* init_settings_frame_parser(grpc_chttp2_transport* t); -static grpc_error* init_window_update_frame_parser(grpc_chttp2_transport* t); -static grpc_error* init_ping_parser(grpc_chttp2_transport* t); -static grpc_error* init_goaway_parser(grpc_chttp2_transport* t); -static grpc_error* init_skip_frame_parser(grpc_chttp2_transport* t, +static grpc_error* init_data_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); +static grpc_error* init_rst_stream_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); +static grpc_error* init_settings_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); +static grpc_error* init_window_update_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); +static grpc_error* init_ping_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); +static grpc_error* init_goaway_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t); +static grpc_error* init_skip_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, int is_header); -static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice, +static grpc_error* parse_frame_slice(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_slice slice, int is_last); -grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, +grpc_error* grpc_chttp2_perform_read(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_slice slice) { uint8_t* beg = GRPC_SLICE_START_PTR(slice); uint8_t* end = GRPC_SLICE_END_PTR(slice); @@ -171,12 +182,12 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, GPR_ASSERT(cur < end); t->incoming_stream_id |= ((uint32_t)*cur); t->deframe_state = GRPC_DTS_FRAME; - err = init_frame_parser(t); + err = init_frame_parser(exec_ctx, t); if (err != GRPC_ERROR_NONE) { return err; } if (t->incoming_frame_size == 0) { - err = parse_frame_slice(t, grpc_empty_slice(), 1); + err = parse_frame_slice(exec_ctx, t, grpc_empty_slice(), 1); if (err != GRPC_ERROR_NONE) { return err; } @@ -206,7 +217,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, GPR_ASSERT(cur < end); if ((uint32_t)(end - cur) == t->incoming_frame_size) { err = - parse_frame_slice(t, + parse_frame_slice(exec_ctx, t, grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), (size_t)(end - beg)), 1); @@ -219,7 +230,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, } else if ((uint32_t)(end - cur) > t->incoming_frame_size) { size_t cur_offset = (size_t)(cur - beg); err = parse_frame_slice( - t, + exec_ctx, t, grpc_slice_sub_no_ref(slice, cur_offset, cur_offset + t->incoming_frame_size), 1); @@ -231,7 +242,7 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, goto dts_fh_0; /* loop */ } else { err = - parse_frame_slice(t, + parse_frame_slice(exec_ctx, t, grpc_slice_sub_no_ref(slice, (size_t)(cur - beg), (size_t)(end - beg)), 0); @@ -247,7 +258,8 @@ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, GPR_UNREACHABLE_CODE(return nullptr); } -static grpc_error* init_frame_parser(grpc_chttp2_transport* t) { +static grpc_error* init_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { if (t->is_first_frame && t->incoming_frame_type != GRPC_CHTTP2_FRAME_SETTINGS) { char* msg; @@ -279,43 +291,46 @@ static grpc_error* init_frame_parser(grpc_chttp2_transport* t) { gpr_free(msg); return err; } - return init_header_frame_parser(t, 1); + return init_header_frame_parser(exec_ctx, t, 1); } switch (t->incoming_frame_type) { case GRPC_CHTTP2_FRAME_DATA: - return init_data_frame_parser(t); + return init_data_frame_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_HEADER: - return init_header_frame_parser(t, 0); + return init_header_frame_parser(exec_ctx, t, 0); case GRPC_CHTTP2_FRAME_CONTINUATION: return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Unexpected CONTINUATION frame"); case GRPC_CHTTP2_FRAME_RST_STREAM: - return init_rst_stream_parser(t); + return init_rst_stream_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_SETTINGS: - return init_settings_frame_parser(t); + return init_settings_frame_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_WINDOW_UPDATE: - return init_window_update_frame_parser(t); + return init_window_update_frame_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_PING: - return init_ping_parser(t); + return init_ping_parser(exec_ctx, t); case GRPC_CHTTP2_FRAME_GOAWAY: - return init_goaway_parser(t); + return init_goaway_parser(exec_ctx, t); default: if (grpc_http_trace.enabled()) { gpr_log(GPR_ERROR, "Unknown frame type %02x", t->incoming_frame_type); } - return init_skip_frame_parser(t, 0); + return init_skip_frame_parser(exec_ctx, t, 0); } } -static grpc_error* skip_parser(void* parser, grpc_chttp2_transport* t, - grpc_chttp2_stream* s, grpc_slice slice, - int is_last) { +static grpc_error* skip_parser(grpc_exec_ctx* exec_ctx, void* parser, + grpc_chttp2_transport* t, grpc_chttp2_stream* s, + grpc_slice slice, int is_last) { return GRPC_ERROR_NONE; } -static void skip_header(void* tp, grpc_mdelem md) { GRPC_MDELEM_UNREF(md); } +static void skip_header(grpc_exec_ctx* exec_ctx, void* tp, grpc_mdelem md) { + GRPC_MDELEM_UNREF(exec_ctx, md); +} -static grpc_error* init_skip_frame_parser(grpc_chttp2_transport* t, +static grpc_error* init_skip_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, int is_header) { if (is_header) { uint8_t is_eoh = t->expect_continuation_stream_id != 0; @@ -331,11 +346,14 @@ static grpc_error* init_skip_frame_parser(grpc_chttp2_transport* t, return GRPC_ERROR_NONE; } -void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport* t) { - init_skip_frame_parser(t, t->parser == grpc_chttp2_header_parser_parse); +void grpc_chttp2_parsing_become_skip_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { + init_skip_frame_parser(exec_ctx, t, + t->parser == grpc_chttp2_header_parser_parse); } -static grpc_error* init_data_frame_parser(grpc_chttp2_transport* t) { +static grpc_error* init_data_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { grpc_chttp2_stream* s = grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); grpc_error* err = GRPC_ERROR_NONE; @@ -347,17 +365,17 @@ static grpc_error* init_data_frame_parser(grpc_chttp2_transport* t) { err = s->flow_control->RecvData(t->incoming_frame_size); action = s->flow_control->MakeAction(); } - grpc_chttp2_act_on_flowctl_action(action, t, s); + grpc_chttp2_act_on_flowctl_action(exec_ctx, action, t, s); if (err != GRPC_ERROR_NONE) { goto error_handler; } if (s == nullptr) { - return init_skip_frame_parser(t, 0); + return init_skip_frame_parser(exec_ctx, t, 0); } s->received_bytes += t->incoming_frame_size; s->stats.incoming.framing_bytes += 9; if (err == GRPC_ERROR_NONE && s->read_closed) { - return init_skip_frame_parser(t, 0); + return init_skip_frame_parser(exec_ctx, t, 0); } if (err == GRPC_ERROR_NONE) { err = grpc_chttp2_data_parser_begin_frame( @@ -376,13 +394,13 @@ error_handler: } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, nullptr)) { /* handle stream errors by closing the stream */ if (s != nullptr) { - grpc_chttp2_mark_stream_closed(t, s, true, false, err); + grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, false, err); } grpc_slice_buffer_add( &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id, GRPC_HTTP2_PROTOCOL_ERROR, &s->stats.outgoing)); - return init_skip_frame_parser(t, 0); + return init_skip_frame_parser(exec_ctx, t, 0); } else { return err; } @@ -390,7 +408,8 @@ error_handler: static void free_timeout(void* p) { gpr_free(p); } -static void on_initial_header(void* tp, grpc_mdelem md) { +static void on_initial_header(grpc_exec_ctx* exec_ctx, void* tp, + grpc_mdelem md) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp; grpc_chttp2_stream* s = t->incoming_stream; @@ -436,9 +455,9 @@ static void on_initial_header(void* tp, grpc_mdelem md) { } if (timeout != GRPC_MILLIS_INF_FUTURE) { grpc_chttp2_incoming_metadata_buffer_set_deadline( - &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout); + &s->metadata_buffer[0], grpc_exec_ctx_now(exec_ctx) + timeout); } - GRPC_MDELEM_UNREF(md); + GRPC_MDELEM_UNREF(exec_ctx, md); } else { const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); const size_t metadata_size_limit = @@ -450,22 +469,22 @@ static void on_initial_header(void* tp, grpc_mdelem md) { " vs. %" PRIuPTR ")", new_size, metadata_size_limit); grpc_chttp2_cancel_stream( - t, s, + exec_ctx, t, s, grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING( "received initial metadata size exceeds limit"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); - grpc_chttp2_parsing_become_skip_parser(t); + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); s->seen_error = true; - GRPC_MDELEM_UNREF(md); + GRPC_MDELEM_UNREF(exec_ctx, md); } else { - grpc_error* error = - grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md); + grpc_error* error = grpc_chttp2_incoming_metadata_buffer_add( + exec_ctx, &s->metadata_buffer[0], md); if (error != GRPC_ERROR_NONE) { - grpc_chttp2_cancel_stream(t, s, error); - grpc_chttp2_parsing_become_skip_parser(t); + grpc_chttp2_cancel_stream(exec_ctx, t, s, error); + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); s->seen_error = true; - GRPC_MDELEM_UNREF(md); + GRPC_MDELEM_UNREF(exec_ctx, md); } } } @@ -473,7 +492,8 @@ static void on_initial_header(void* tp, grpc_mdelem md) { GPR_TIMER_END("on_initial_header", 0); } -static void on_trailing_header(void* tp, grpc_mdelem md) { +static void on_trailing_header(grpc_exec_ctx* exec_ctx, void* tp, + grpc_mdelem md) { grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp; grpc_chttp2_stream* s = t->incoming_stream; @@ -507,29 +527,30 @@ static void on_trailing_header(void* tp, grpc_mdelem md) { " vs. %" PRIuPTR ")", new_size, metadata_size_limit); grpc_chttp2_cancel_stream( - t, s, + exec_ctx, t, s, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "received trailing metadata size exceeds limit"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); - grpc_chttp2_parsing_become_skip_parser(t); + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); s->seen_error = true; - GRPC_MDELEM_UNREF(md); + GRPC_MDELEM_UNREF(exec_ctx, md); } else { - grpc_error* error = - grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[1], md); + grpc_error* error = grpc_chttp2_incoming_metadata_buffer_add( + exec_ctx, &s->metadata_buffer[1], md); if (error != GRPC_ERROR_NONE) { - grpc_chttp2_cancel_stream(t, s, error); - grpc_chttp2_parsing_become_skip_parser(t); + grpc_chttp2_cancel_stream(exec_ctx, t, s, error); + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); s->seen_error = true; - GRPC_MDELEM_UNREF(md); + GRPC_MDELEM_UNREF(exec_ctx, md); } } GPR_TIMER_END("on_trailing_header", 0); } -static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, +static grpc_error* init_header_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, int is_continuation) { uint8_t is_eoh = (t->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0; @@ -559,7 +580,7 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, GRPC_CHTTP2_IF_TRACING( gpr_log(GPR_ERROR, "grpc_chttp2_stream disbanded before CONTINUATION received")); - return init_skip_frame_parser(t, 1); + return init_skip_frame_parser(exec_ctx, t, 1); } if (t->is_client) { if ((t->incoming_stream_id & 1) && @@ -569,7 +590,7 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, GRPC_CHTTP2_IF_TRACING(gpr_log( GPR_ERROR, "ignoring new grpc_chttp2_stream creation on client")); } - grpc_error* err = init_skip_frame_parser(t, 1); + grpc_error* err = init_skip_frame_parser(exec_ctx, t, 1); if (t->incoming_frame_flags & GRPC_CHTTP2_FLAG_HAS_PRIORITY) { grpc_chttp2_hpack_parser_set_has_priority(&t->hpack_parser); } @@ -581,13 +602,13 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, "last grpc_chttp2_stream " "id=%d, new grpc_chttp2_stream id=%d", t->last_new_stream_id, t->incoming_stream_id)); - return init_skip_frame_parser(t, 1); + return init_skip_frame_parser(exec_ctx, t, 1); } else if ((t->incoming_stream_id & 1) == 0) { GRPC_CHTTP2_IF_TRACING(gpr_log( GPR_ERROR, "ignoring grpc_chttp2_stream with non-client generated index %d", t->incoming_stream_id)); - return init_skip_frame_parser(t, 1); + return init_skip_frame_parser(exec_ctx, t, 1); } else if (grpc_chttp2_stream_map_size(&t->stream_map) >= t->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]) { @@ -595,11 +616,11 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, } t->last_new_stream_id = t->incoming_stream_id; s = t->incoming_stream = - grpc_chttp2_parsing_accept_stream(t, t->incoming_stream_id); + grpc_chttp2_parsing_accept_stream(exec_ctx, t, t->incoming_stream_id); if (s == nullptr) { GRPC_CHTTP2_IF_TRACING( gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted")); - return init_skip_frame_parser(t, 1); + return init_skip_frame_parser(exec_ctx, t, 1); } } else { t->incoming_stream = s; @@ -610,7 +631,7 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, GRPC_CHTTP2_IF_TRACING(gpr_log( GPR_ERROR, "skipping already closed grpc_chttp2_stream header")); t->incoming_stream = nullptr; - return init_skip_frame_parser(t, 1); + return init_skip_frame_parser(exec_ctx, t, 1); } t->parser = grpc_chttp2_header_parser_parse; t->parser_data = &t->hpack_parser; @@ -635,7 +656,7 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, break; case 2: gpr_log(GPR_ERROR, "too many header frames received"); - return init_skip_frame_parser(t, 1); + return init_skip_frame_parser(exec_ctx, t, 1); } t->hpack_parser.on_header_user_data = t; t->hpack_parser.is_boundary = is_eoh; @@ -647,7 +668,8 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, return GRPC_ERROR_NONE; } -static grpc_error* init_window_update_frame_parser(grpc_chttp2_transport* t) { +static grpc_error* init_window_update_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { grpc_error* err = grpc_chttp2_window_update_parser_begin_frame( &t->simple.window_update, t->incoming_frame_size, t->incoming_frame_flags); @@ -656,7 +678,7 @@ static grpc_error* init_window_update_frame_parser(grpc_chttp2_transport* t) { grpc_chttp2_stream* s = t->incoming_stream = grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); if (s == nullptr) { - return init_skip_frame_parser(t, 0); + return init_skip_frame_parser(exec_ctx, t, 0); } s->stats.incoming.framing_bytes += 9; } @@ -665,7 +687,8 @@ static grpc_error* init_window_update_frame_parser(grpc_chttp2_transport* t) { return GRPC_ERROR_NONE; } -static grpc_error* init_ping_parser(grpc_chttp2_transport* t) { +static grpc_error* init_ping_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { grpc_error* err = grpc_chttp2_ping_parser_begin_frame( &t->simple.ping, t->incoming_frame_size, t->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; @@ -674,14 +697,15 @@ static grpc_error* init_ping_parser(grpc_chttp2_transport* t) { return GRPC_ERROR_NONE; } -static grpc_error* init_rst_stream_parser(grpc_chttp2_transport* t) { +static grpc_error* init_rst_stream_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { grpc_error* err = grpc_chttp2_rst_stream_parser_begin_frame( &t->simple.rst_stream, t->incoming_frame_size, t->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; grpc_chttp2_stream* s = t->incoming_stream = grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); if (!t->incoming_stream) { - return init_skip_frame_parser(t, 0); + return init_skip_frame_parser(exec_ctx, t, 0); } s->stats.incoming.framing_bytes += 9; t->parser = grpc_chttp2_rst_stream_parser_parse; @@ -689,7 +713,8 @@ static grpc_error* init_rst_stream_parser(grpc_chttp2_transport* t) { return GRPC_ERROR_NONE; } -static grpc_error* init_goaway_parser(grpc_chttp2_transport* t) { +static grpc_error* init_goaway_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { grpc_error* err = grpc_chttp2_goaway_parser_begin_frame( &t->goaway_parser, t->incoming_frame_size, t->incoming_frame_flags); if (err != GRPC_ERROR_NONE) return err; @@ -698,7 +723,8 @@ static grpc_error* init_goaway_parser(grpc_chttp2_transport* t) { return GRPC_ERROR_NONE; } -static grpc_error* init_settings_frame_parser(grpc_chttp2_transport* t) { +static grpc_error* init_settings_frame_parser(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { if (t->incoming_stream_id != 0) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Settings frame received for grpc_chttp2_stream"); @@ -714,7 +740,7 @@ static grpc_error* init_settings_frame_parser(grpc_chttp2_transport* t) { memcpy(t->settings[GRPC_ACKED_SETTINGS], t->settings[GRPC_SENT_SETTINGS], GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t)); grpc_chttp2_hptbl_set_max_bytes( - &t->hpack_parser.table, + exec_ctx, &t->hpack_parser.table, t->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); t->sent_local_settings = 0; @@ -724,10 +750,11 @@ static grpc_error* init_settings_frame_parser(grpc_chttp2_transport* t) { return GRPC_ERROR_NONE; } -static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice, +static grpc_error* parse_frame_slice(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t, grpc_slice slice, int is_last) { grpc_chttp2_stream* s = t->incoming_stream; - grpc_error* err = t->parser(t->parser_data, t, s, slice, is_last); + grpc_error* err = t->parser(exec_ctx, t->parser_data, t, s, slice, is_last); if (err == GRPC_ERROR_NONE) { return err; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, nullptr)) { @@ -735,7 +762,7 @@ static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice, const char* msg = grpc_error_string(err); gpr_log(GPR_ERROR, "%s", msg); } - grpc_chttp2_parsing_become_skip_parser(t); + grpc_chttp2_parsing_become_skip_parser(exec_ctx, t); if (s) { s->forced_close_error = err; grpc_slice_buffer_add( diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 3310f35f5f..204b5a7708 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -33,15 +33,17 @@ static void add_to_write_list(grpc_chttp2_write_cb** list, *list = cb; } -static void finish_write_cb(grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_chttp2_write_cb* cb, grpc_error* error) { - grpc_chttp2_complete_closure_step(t, s, &cb->closure, error, +static void finish_write_cb(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_chttp2_stream* s, grpc_chttp2_write_cb* cb, + grpc_error* error) { + grpc_chttp2_complete_closure_step(exec_ctx, t, s, &cb->closure, error, "finish_write_cb"); cb->next = t->write_cb_pool; t->write_cb_pool = cb; } -static void maybe_initiate_ping(grpc_chttp2_transport* t) { +static void maybe_initiate_ping(grpc_exec_ctx* exec_ctx, + grpc_chttp2_transport* t) { grpc_chttp2_ping_queue* pq = &t->ping_queue; if (grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_NEXT])) { /* no ping needed: wait */ @@ -66,7 +68,7 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) { } return; } - grpc_millis now = grpc_core::ExecCtx::Get()->Now(); + grpc_millis now = grpc_exec_ctx_now(exec_ctx); grpc_millis next_allowed_ping = t->ping_state.last_ping_sent_time + t->ping_policy.min_sent_ping_interval_without_data; @@ -87,20 +89,20 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) { } if (!t->ping_state.is_delayed_ping_timer_set) { t->ping_state.is_delayed_ping_timer_set = true; - grpc_timer_init(&t->ping_state.delayed_ping_timer, next_allowed_ping, - &t->retry_initiate_ping_locked); + grpc_timer_init(exec_ctx, &t->ping_state.delayed_ping_timer, + next_allowed_ping, &t->retry_initiate_ping_locked); } return; } pq->inflight_id = t->ping_ctr; t->ping_ctr++; - GRPC_CLOSURE_LIST_SCHED(&pq->lists[GRPC_CHTTP2_PCL_INITIATE]); + GRPC_CLOSURE_LIST_SCHED(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INITIATE]); grpc_closure_list_move(&pq->lists[GRPC_CHTTP2_PCL_NEXT], &pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]); grpc_slice_buffer_add(&t->outbuf, grpc_chttp2_ping_create(false, pq->inflight_id)); - GRPC_STATS_INC_HTTP2_PINGS_SENT(); + GRPC_STATS_INC_HTTP2_PINGS_SENT(exec_ctx); t->ping_state.last_ping_sent_time = now; if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) { gpr_log(GPR_DEBUG, "%s: Ping sent [%p]: %d/%d", @@ -112,9 +114,10 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) { (t->ping_state.pings_before_data_required != 0); } -static bool update_list(grpc_chttp2_transport* t, grpc_chttp2_stream* s, - int64_t send_bytes, grpc_chttp2_write_cb** list, - int64_t* ctr, grpc_error* error) { +static bool update_list(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_chttp2_stream* s, int64_t send_bytes, + grpc_chttp2_write_cb** list, int64_t* ctr, + grpc_error* error) { bool sched_any = false; grpc_chttp2_write_cb* cb = *list; *list = nullptr; @@ -123,7 +126,7 @@ static bool update_list(grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_chttp2_write_cb* next = cb->next; if (cb->call_at_byte <= *ctr) { sched_any = true; - finish_write_cb(t, s, cb, GRPC_ERROR_REF(error)); + finish_write_cb(exec_ctx, t, s, cb, GRPC_ERROR_REF(error)); } else { add_to_write_list(list, cb); } @@ -176,22 +179,22 @@ class StreamWriteContext; class WriteContext { public: - WriteContext(grpc_chttp2_transport* t) : t_(t) { - GRPC_STATS_INC_HTTP2_WRITES_BEGUN(); + WriteContext(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t) : t_(t) { + GRPC_STATS_INC_HTTP2_WRITES_BEGUN(exec_ctx); GPR_TIMER_BEGIN("grpc_chttp2_begin_write", 0); } // TODO(ctiller): make this the destructor - void FlushStats() { + void FlushStats(grpc_exec_ctx* exec_ctx) { GRPC_STATS_INC_HTTP2_SEND_INITIAL_METADATA_PER_WRITE( - initial_metadata_writes_); - GRPC_STATS_INC_HTTP2_SEND_MESSAGE_PER_WRITE(message_writes_); + exec_ctx, initial_metadata_writes_); + GRPC_STATS_INC_HTTP2_SEND_MESSAGE_PER_WRITE(exec_ctx, message_writes_); GRPC_STATS_INC_HTTP2_SEND_TRAILING_METADATA_PER_WRITE( - trailing_metadata_writes_); - GRPC_STATS_INC_HTTP2_SEND_FLOWCTL_PER_WRITE(flow_control_writes_); + exec_ctx, trailing_metadata_writes_); + GRPC_STATS_INC_HTTP2_SEND_FLOWCTL_PER_WRITE(exec_ctx, flow_control_writes_); } - void FlushSettings() { + void FlushSettings(grpc_exec_ctx* exec_ctx) { if (t_->dirtied_local_settings && !t_->sent_local_settings) { grpc_slice_buffer_add( &t_->outbuf, grpc_chttp2_settings_create( @@ -201,17 +204,17 @@ class WriteContext { t_->force_send_settings = false; t_->dirtied_local_settings = false; t_->sent_local_settings = true; - GRPC_STATS_INC_HTTP2_SETTINGS_WRITES(); + GRPC_STATS_INC_HTTP2_SETTINGS_WRITES(exec_ctx); } } - void FlushQueuedBuffers() { + void FlushQueuedBuffers(grpc_exec_ctx* exec_ctx) { /* simple writes are queued to qbuf, and flushed here */ grpc_slice_buffer_move_into(&t_->qbuf, &t_->outbuf); GPR_ASSERT(t_->qbuf.count == 0); } - void FlushWindowUpdates() { + void FlushWindowUpdates(grpc_exec_ctx* exec_ctx) { uint32_t transport_announce = t_->flow_control->MaybeSendUpdate(t_->outbuf.count > 0); if (transport_announce) { @@ -231,7 +234,7 @@ class WriteContext { t_->ping_ack_count = 0; } - void EnactHpackSettings() { + void EnactHpackSettings(grpc_exec_ctx* exec_ctx) { grpc_chttp2_hpack_compressor_set_max_table_size( &t_->hpack_compressor, t_->settings[GRPC_PEER_SETTINGS] @@ -371,8 +374,8 @@ class DataSendContext { bool is_last_frame() const { return is_last_frame_; } - void CallCallbacks() { - if (update_list(t_, s_, + void CallCallbacks(grpc_exec_ctx* exec_ctx) { + if (update_list(exec_ctx, t_, s_, (int64_t)(s_->sending_bytes - sending_bytes_before_), &s_->on_flow_controlled_cbs, &s_->flow_controlled_bytes_flowed, GRPC_ERROR_NONE)) { @@ -400,7 +403,7 @@ class StreamWriteContext { s->flow_control->announced_window_delta()))); } - void FlushInitialMetadata() { + void FlushInitialMetadata(grpc_exec_ctx* exec_ctx) { /* send initial metadata if it's available */ if (s_->sent_initial_metadata) return; if (s_->send_initial_metadata == nullptr) return; @@ -427,7 +430,7 @@ class StreamWriteContext { [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], // max_frame_size &s_->stats.outgoing // stats }; - grpc_chttp2_encode_header(&t_->hpack_compressor, nullptr, 0, + grpc_chttp2_encode_header(exec_ctx, &t_->hpack_compressor, nullptr, 0, s_->send_initial_metadata, &hopt, &t_->outbuf); write_context_->ResetPingRecvClock(); write_context_->IncInitialMetadataWrites(); @@ -437,11 +440,11 @@ class StreamWriteContext { s_->sent_initial_metadata = true; write_context_->NoteScheduledResults(); grpc_chttp2_complete_closure_step( - t_, s_, &s_->send_initial_metadata_finished, GRPC_ERROR_NONE, + exec_ctx, t_, s_, &s_->send_initial_metadata_finished, GRPC_ERROR_NONE, "send_initial_metadata_finished"); } - void FlushWindowUpdates() { + void FlushWindowUpdates(grpc_exec_ctx* exec_ctx) { /* send any window updates */ const uint32_t stream_announce = s_->flow_control->MaybeSendUpdate(); if (stream_announce == 0) return; @@ -453,7 +456,7 @@ class StreamWriteContext { write_context_->IncWindowUpdateWrites(); } - void FlushData() { + void FlushData(grpc_exec_ctx* exec_ctx) { if (!s_->sent_initial_metadata) return; if (s_->flow_controlled_buffer.length == 0 && @@ -485,9 +488,9 @@ class StreamWriteContext { } write_context_->ResetPingRecvClock(); if (data_send_context.is_last_frame()) { - SentLastFrame(); + SentLastFrame(exec_ctx); } - data_send_context.CallCallbacks(); + data_send_context.CallCallbacks(exec_ctx); stream_became_writable_ = true; if (s_->flow_controlled_buffer.length > 0 || s_->compressed_data_buffer.length > 0) { @@ -497,7 +500,7 @@ class StreamWriteContext { write_context_->IncMessageWrites(); } - void FlushTrailingMetadata() { + void FlushTrailingMetadata(grpc_exec_ctx* exec_ctx) { if (!s_->sent_initial_metadata) return; if (s_->send_trailing_metadata == nullptr) return; @@ -518,18 +521,18 @@ class StreamWriteContext { t_->settings[GRPC_PEER_SETTINGS][GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], &s_->stats.outgoing}; - grpc_chttp2_encode_header(&t_->hpack_compressor, + grpc_chttp2_encode_header(exec_ctx, &t_->hpack_compressor, extra_headers_for_trailing_metadata_, num_extra_headers_for_trailing_metadata_, s_->send_trailing_metadata, &hopt, &t_->outbuf); } write_context_->IncTrailingMetadataWrites(); write_context_->ResetPingRecvClock(); - SentLastFrame(); + SentLastFrame(exec_ctx); write_context_->NoteScheduledResults(); grpc_chttp2_complete_closure_step( - t_, s_, &s_->send_trailing_metadata_finished, GRPC_ERROR_NONE, + exec_ctx, t_, s_, &s_->send_trailing_metadata_finished, GRPC_ERROR_NONE, "send_trailing_metadata_finished"); } @@ -553,7 +556,7 @@ class StreamWriteContext { } } - void SentLastFrame() { + void SentLastFrame(grpc_exec_ctx* exec_ctx) { s_->send_trailing_metadata = nullptr; s_->sent_trailing_metadata = true; @@ -562,7 +565,7 @@ class StreamWriteContext { &t_->outbuf, grpc_chttp2_rst_stream_create( s_->id, GRPC_HTTP2_NO_ERROR, &s_->stats.outgoing)); } - grpc_chttp2_mark_stream_closed(t_, s_, !t_->is_client, true, + grpc_chttp2_mark_stream_closed(exec_ctx, t_, s_, !t_->is_client, true, GRPC_ERROR_NONE); } @@ -576,12 +579,12 @@ class StreamWriteContext { } // namespace grpc_chttp2_begin_write_result grpc_chttp2_begin_write( - grpc_chttp2_transport* t) { - WriteContext ctx(t); - ctx.FlushSettings(); + grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t) { + WriteContext ctx(exec_ctx, t); + ctx.FlushSettings(exec_ctx); ctx.FlushPingAcks(); - ctx.FlushQueuedBuffers(); - ctx.EnactHpackSettings(); + ctx.FlushQueuedBuffers(exec_ctx); + ctx.EnactHpackSettings(exec_ctx); if (t->flow_control->remote_window() > 0) { ctx.UpdateStreamsNoLongerStalled(); @@ -591,45 +594,47 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( (according to available window sizes) and add to the output buffer */ while (grpc_chttp2_stream* s = ctx.NextStream()) { StreamWriteContext stream_ctx(&ctx, s); - stream_ctx.FlushInitialMetadata(); - stream_ctx.FlushWindowUpdates(); - stream_ctx.FlushData(); - stream_ctx.FlushTrailingMetadata(); + stream_ctx.FlushInitialMetadata(exec_ctx); + stream_ctx.FlushWindowUpdates(exec_ctx); + stream_ctx.FlushData(exec_ctx); + stream_ctx.FlushTrailingMetadata(exec_ctx); if (stream_ctx.stream_became_writable()) { if (!grpc_chttp2_list_add_writing_stream(t, s)) { /* already in writing list: drop ref */ - GRPC_CHTTP2_STREAM_UNREF(s, "chttp2_writing:already_writing"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:already_writing"); } else { /* ref will be dropped at end of write */ } } else { - GRPC_CHTTP2_STREAM_UNREF(s, "chttp2_writing:no_write"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:no_write"); } } - ctx.FlushWindowUpdates(); + ctx.FlushWindowUpdates(exec_ctx); - maybe_initiate_ping(t); + maybe_initiate_ping(exec_ctx, t); GPR_TIMER_END("grpc_chttp2_begin_write", 0); return ctx.Result(); } -void grpc_chttp2_end_write(grpc_chttp2_transport* t, grpc_error* error) { +void grpc_chttp2_end_write(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, + grpc_error* error) { GPR_TIMER_BEGIN("grpc_chttp2_end_write", 0); grpc_chttp2_stream* s; while (grpc_chttp2_list_pop_writing_stream(t, &s)) { if (s->sending_bytes != 0) { - update_list(t, s, (int64_t)s->sending_bytes, &s->on_write_finished_cbs, - &s->flow_controlled_bytes_written, GRPC_ERROR_REF(error)); + update_list(exec_ctx, t, s, (int64_t)s->sending_bytes, + &s->on_write_finished_cbs, &s->flow_controlled_bytes_written, + GRPC_ERROR_REF(error)); s->sending_bytes = 0; } - GRPC_CHTTP2_STREAM_UNREF(s, "chttp2_writing:end"); + GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:end"); } - grpc_slice_buffer_reset_and_unref_internal(&t->outbuf); + grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &t->outbuf); GRPC_ERROR_UNREF(error); GPR_TIMER_END("grpc_chttp2_end_write", 0); } diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc index 40a30e4a31..d590ba0371 100644 --- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc +++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc @@ -49,6 +49,7 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( grpc_transport* ct = grpc_create_cronet_transport(engine, target, args, reserved); - grpc_core::ExecCtx exec_ctx; - return grpc_channel_create(target, args, GRPC_CLIENT_DIRECT_CHANNEL, ct); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + return grpc_channel_create(&exec_ctx, target, args, + GRPC_CLIENT_DIRECT_CHANNEL, ct); } diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index c9fd94176b..4d24efe47b 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -197,23 +197,27 @@ typedef struct stream_obj stream_obj; #ifndef NDEBUG #define GRPC_CRONET_STREAM_REF(stream, reason) \ grpc_cronet_stream_ref((stream), (reason)) -#define GRPC_CRONET_STREAM_UNREF(stream, reason) \ - grpc_cronet_stream_unref((stream), (reason)) +#define GRPC_CRONET_STREAM_UNREF(exec_ctx, stream, reason) \ + grpc_cronet_stream_unref((exec_ctx), (stream), (reason)) void grpc_cronet_stream_ref(stream_obj* s, const char* reason) { grpc_stream_ref(s->refcount, reason); } -void grpc_cronet_stream_unref(stream_obj* s, const char* reason) { - grpc_stream_unref(s->refcount, reason); +void grpc_cronet_stream_unref(grpc_exec_ctx* exec_ctx, stream_obj* s, + const char* reason) { + grpc_stream_unref(exec_ctx, s->refcount, reason); } #else #define GRPC_CRONET_STREAM_REF(stream, reason) grpc_cronet_stream_ref((stream)) -#define GRPC_CRONET_STREAM_UNREF(stream, reason) \ - grpc_cronet_stream_unref((stream)) +#define GRPC_CRONET_STREAM_UNREF(exec_ctx, stream, reason) \ + grpc_cronet_stream_unref((exec_ctx), (stream)) void grpc_cronet_stream_ref(stream_obj* s) { grpc_stream_ref(s->refcount); } -void grpc_cronet_stream_unref(stream_obj* s) { grpc_stream_unref(s->refcount); } +void grpc_cronet_stream_unref(grpc_exec_ctx* exec_ctx, stream_obj* s) { + grpc_stream_unref(exec_ctx, s->refcount); +} #endif -static enum e_op_result execute_stream_op(struct op_and_state* oas); +static enum e_op_result execute_stream_op(grpc_exec_ctx* exec_ctx, + struct op_and_state* oas); /* Utility function to translate enum into string for printing @@ -369,12 +373,12 @@ static void remove_from_storage(struct stream_obj* s, This can get executed from the Cronet network thread via cronet callback or on the application supplied thread via the perform_stream_op function. */ -static void execute_from_storage(stream_obj* s) { +static void execute_from_storage(grpc_exec_ctx* exec_ctx, stream_obj* s) { gpr_mu_lock(&s->mu); for (struct op_and_state* curr = s->storage.head; curr != nullptr;) { CRONET_LOG(GPR_DEBUG, "calling op at %p. done = %d", curr, curr->done); GPR_ASSERT(curr->done == 0); - enum e_op_result result = execute_stream_op(curr); + enum e_op_result result = execute_stream_op(exec_ctx, curr); CRONET_LOG(GPR_DEBUG, "execute_stream_op[%p] returns %s", curr, op_result_string(result)); /* if this op is done, then remove it and free memory */ @@ -398,7 +402,7 @@ static void execute_from_storage(stream_obj* s) { */ static void on_failed(bidirectional_stream* stream, int net_error) { CRONET_LOG(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error); - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; stream_obj* s = (stream_obj*)stream->annotation; gpr_mu_lock(&s->mu); @@ -415,8 +419,9 @@ static void on_failed(bidirectional_stream* stream, int net_error) { } null_and_maybe_free_read_buffer(s); gpr_mu_unlock(&s->mu); - execute_from_storage(s); - GRPC_CRONET_STREAM_UNREF(s, "cronet transport"); + execute_from_storage(&exec_ctx, s); + GRPC_CRONET_STREAM_UNREF(&exec_ctx, s, "cronet transport"); + grpc_exec_ctx_finish(&exec_ctx); } /* @@ -424,7 +429,7 @@ static void on_failed(bidirectional_stream* stream, int net_error) { */ static void on_canceled(bidirectional_stream* stream) { CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream); - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; stream_obj* s = (stream_obj*)stream->annotation; gpr_mu_lock(&s->mu); @@ -441,8 +446,9 @@ static void on_canceled(bidirectional_stream* stream) { } null_and_maybe_free_read_buffer(s); gpr_mu_unlock(&s->mu); - execute_from_storage(s); - GRPC_CRONET_STREAM_UNREF(s, "cronet transport"); + execute_from_storage(&exec_ctx, s); + GRPC_CRONET_STREAM_UNREF(&exec_ctx, s, "cronet transport"); + grpc_exec_ctx_finish(&exec_ctx); } /* @@ -450,7 +456,7 @@ static void on_canceled(bidirectional_stream* stream) { */ static void on_succeeded(bidirectional_stream* stream) { CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream); - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; stream_obj* s = (stream_obj*)stream->annotation; gpr_mu_lock(&s->mu); @@ -459,8 +465,9 @@ static void on_succeeded(bidirectional_stream* stream) { s->cbs = nullptr; null_and_maybe_free_read_buffer(s); gpr_mu_unlock(&s->mu); - execute_from_storage(s); - GRPC_CRONET_STREAM_UNREF(s, "cronet transport"); + execute_from_storage(&exec_ctx, s); + GRPC_CRONET_STREAM_UNREF(&exec_ctx, s, "cronet transport"); + grpc_exec_ctx_finish(&exec_ctx); } /* @@ -468,7 +475,7 @@ static void on_succeeded(bidirectional_stream* stream) { */ static void on_stream_ready(bidirectional_stream* stream) { CRONET_LOG(GPR_DEBUG, "W: on_stream_ready(%p)", stream); - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; stream_obj* s = (stream_obj*)stream->annotation; grpc_cronet_transport* t = (grpc_cronet_transport*)s->curr_ct; gpr_mu_lock(&s->mu); @@ -488,7 +495,8 @@ static void on_stream_ready(bidirectional_stream* stream) { } } gpr_mu_unlock(&s->mu); - execute_from_storage(s); + execute_from_storage(&exec_ctx, s); + grpc_exec_ctx_finish(&exec_ctx); } /* @@ -498,7 +506,7 @@ static void on_response_headers_received( bidirectional_stream* stream, const bidirectional_stream_header_array* headers, const char* negotiated_protocol) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, headers, negotiated_protocol); stream_obj* s = (stream_obj*)stream->annotation; @@ -520,8 +528,9 @@ static void on_response_headers_received( for (size_t i = 0; i < headers->count; i++) { GRPC_LOG_IF_ERROR("on_response_headers_received", grpc_chttp2_incoming_metadata_buffer_add( - &s->state.rs.initial_metadata, + &exec_ctx, &s->state.rs.initial_metadata, grpc_mdelem_from_slices( + &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string( headers->headers[i].key)), grpc_slice_intern(grpc_slice_from_static_string( @@ -543,14 +552,15 @@ static void on_response_headers_received( s->state.pending_read_from_cronet = true; } gpr_mu_unlock(&s->mu); - execute_from_storage(s); + execute_from_storage(&exec_ctx, s); + grpc_exec_ctx_finish(&exec_ctx); } /* Cronet callback */ static void on_write_completed(bidirectional_stream* stream, const char* data) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; stream_obj* s = (stream_obj*)stream->annotation; CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); gpr_mu_lock(&s->mu); @@ -560,7 +570,8 @@ static void on_write_completed(bidirectional_stream* stream, const char* data) { } s->state.state_callback_received[OP_SEND_MESSAGE] = true; gpr_mu_unlock(&s->mu); - execute_from_storage(s); + execute_from_storage(&exec_ctx, s); + grpc_exec_ctx_finish(&exec_ctx); } /* @@ -568,7 +579,7 @@ static void on_write_completed(bidirectional_stream* stream, const char* data) { */ static void on_read_completed(bidirectional_stream* stream, char* data, int count) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; stream_obj* s = (stream_obj*)stream->annotation; CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, count); @@ -594,14 +605,15 @@ static void on_read_completed(bidirectional_stream* stream, char* data, gpr_mu_unlock(&s->mu); } else { gpr_mu_unlock(&s->mu); - execute_from_storage(s); + execute_from_storage(&exec_ctx, s); } } else { null_and_maybe_free_read_buffer(s); s->state.rs.read_stream_closed = true; gpr_mu_unlock(&s->mu); - execute_from_storage(s); + execute_from_storage(&exec_ctx, s); } + grpc_exec_ctx_finish(&exec_ctx); } /* @@ -610,7 +622,7 @@ static void on_read_completed(bidirectional_stream* stream, char* data, static void on_response_trailers_received( bidirectional_stream* stream, const bidirectional_stream_header_array* trailers) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, trailers); stream_obj* s = (stream_obj*)stream->annotation; @@ -626,8 +638,9 @@ static void on_response_trailers_received( trailers->headers[i].value); GRPC_LOG_IF_ERROR("on_response_trailers_received", grpc_chttp2_incoming_metadata_buffer_add( - &s->state.rs.trailing_metadata, + &exec_ctx, &s->state.rs.trailing_metadata, grpc_mdelem_from_slices( + &exec_ctx, grpc_slice_intern(grpc_slice_from_static_string( trailers->headers[i].key)), grpc_slice_intern(grpc_slice_from_static_string( @@ -657,15 +670,17 @@ static void on_response_trailers_received( gpr_mu_unlock(&s->mu); } else { gpr_mu_unlock(&s->mu); - execute_from_storage(s); + execute_from_storage(&exec_ctx, s); } + grpc_exec_ctx_finish(&exec_ctx); } /* Utility function that takes the data from s->write_slice_buffer and assembles into a contiguous byte stream with 5 byte gRPC header prepended. */ -static void create_grpc_frame(grpc_slice_buffer* write_slice_buffer, +static void create_grpc_frame(grpc_exec_ctx* exec_ctx, + grpc_slice_buffer* write_slice_buffer, char** pp_write_buffer, size_t* p_write_buffer_size, uint32_t flags) { grpc_slice slice = grpc_slice_buffer_take_first(write_slice_buffer); @@ -685,7 +700,7 @@ static void create_grpc_frame(grpc_slice_buffer* write_slice_buffer, *p++ = (uint8_t)(length); /* append actual data */ memcpy(p, GRPC_SLICE_START_PTR(slice), length); - grpc_slice_unref_internal(slice); + grpc_slice_unref_internal(exec_ctx, slice); } /* @@ -966,7 +981,8 @@ static bool op_can_be_run(grpc_transport_stream_op_batch* curr_op, /* TODO (makdharma): Break down this function in smaller chunks for readability. */ -static enum e_op_result execute_stream_op(struct op_and_state* oas) { +static enum e_op_result execute_stream_op(grpc_exec_ctx* exec_ctx, + struct op_and_state* oas) { grpc_transport_stream_op_batch* stream_op = &oas->op; struct stream_obj* s = oas->s; grpc_cronet_transport* t = (grpc_cronet_transport*)s->curr_ct; @@ -1024,14 +1040,15 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { grpc_slice slice; grpc_slice_buffer_init(&write_slice_buffer); if (1 != grpc_byte_stream_next( - stream_op->payload->send_message.send_message, + exec_ctx, stream_op->payload->send_message.send_message, stream_op->payload->send_message.send_message->length, nullptr)) { /* Should never reach here */ GPR_ASSERT(false); } if (GRPC_ERROR_NONE != - grpc_byte_stream_pull(stream_op->payload->send_message.send_message, + grpc_byte_stream_pull(exec_ctx, + stream_op->payload->send_message.send_message, &slice)) { /* Should never reach here */ GPR_ASSERT(false); @@ -1044,15 +1061,15 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { } if (write_slice_buffer.count > 0) { size_t write_buffer_size; - create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer, - &write_buffer_size, + create_grpc_frame(exec_ctx, &write_slice_buffer, + &stream_state->ws.write_buffer, &write_buffer_size, stream_op->payload->send_message.send_message->flags); CRONET_LOG(GPR_DEBUG, "bidirectional_stream_write (%p, %p)", s->cbs, stream_state->ws.write_buffer); stream_state->state_callback_received[OP_SEND_MESSAGE] = false; bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer, (int)write_buffer_size, false); - grpc_slice_buffer_destroy_internal(&write_slice_buffer); + grpc_slice_buffer_destroy_internal(exec_ctx, &write_slice_buffer); if (t->use_packet_coalescing) { if (!stream_op->send_trailing_metadata) { CRONET_LOG(GPR_DEBUG, "bidirectional_stream_flush (%p)", s->cbs); @@ -1095,21 +1112,25 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_INITIAL_METADATA", oas); if (stream_state->state_op_done[OP_CANCEL_ERROR]) { GRPC_CLOSURE_SCHED( + exec_ctx, stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready, GRPC_ERROR_NONE); } else if (stream_state->state_callback_received[OP_FAILED]) { GRPC_CLOSURE_SCHED( + exec_ctx, stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready, GRPC_ERROR_NONE); } else if (stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) { GRPC_CLOSURE_SCHED( + exec_ctx, stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready, GRPC_ERROR_NONE); } else { grpc_chttp2_incoming_metadata_buffer_publish( - &oas->s->state.rs.initial_metadata, + exec_ctx, &oas->s->state.rs.initial_metadata, stream_op->payload->recv_initial_metadata.recv_initial_metadata); GRPC_CLOSURE_SCHED( + exec_ctx, stream_op->payload->recv_initial_metadata.recv_initial_metadata_ready, GRPC_ERROR_NONE); } @@ -1120,14 +1141,16 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_MESSAGE", oas); if (stream_state->state_op_done[OP_CANCEL_ERROR]) { CRONET_LOG(GPR_DEBUG, "Stream is cancelled."); - GRPC_CLOSURE_SCHED(stream_op->payload->recv_message.recv_message_ready, + GRPC_CLOSURE_SCHED(exec_ctx, + stream_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); stream_state->state_op_done[OP_RECV_MESSAGE] = true; oas->state.state_op_done[OP_RECV_MESSAGE] = true; result = ACTION_TAKEN_NO_CALLBACK; } else if (stream_state->state_callback_received[OP_FAILED]) { CRONET_LOG(GPR_DEBUG, "Stream failed."); - GRPC_CLOSURE_SCHED(stream_op->payload->recv_message.recv_message_ready, + GRPC_CLOSURE_SCHED(exec_ctx, + stream_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); stream_state->state_op_done[OP_RECV_MESSAGE] = true; oas->state.state_op_done[OP_RECV_MESSAGE] = true; @@ -1135,14 +1158,16 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { } else if (stream_state->rs.read_stream_closed == true) { /* No more data will be received */ CRONET_LOG(GPR_DEBUG, "read stream closed"); - GRPC_CLOSURE_SCHED(stream_op->payload->recv_message.recv_message_ready, + GRPC_CLOSURE_SCHED(exec_ctx, + stream_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); stream_state->state_op_done[OP_RECV_MESSAGE] = true; oas->state.state_op_done[OP_RECV_MESSAGE] = true; result = ACTION_TAKEN_NO_CALLBACK; } else if (stream_state->flush_read) { CRONET_LOG(GPR_DEBUG, "flush read"); - GRPC_CLOSURE_SCHED(stream_op->payload->recv_message.recv_message_ready, + GRPC_CLOSURE_SCHED(exec_ctx, + stream_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); stream_state->state_op_done[OP_RECV_MESSAGE] = true; oas->state.state_op_done[OP_RECV_MESSAGE] = true; @@ -1175,7 +1200,7 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { CRONET_LOG(GPR_DEBUG, "read operation complete. Empty response."); /* Clean up read_slice_buffer in case there is unread data. */ grpc_slice_buffer_destroy_internal( - &stream_state->rs.read_slice_buffer); + exec_ctx, &stream_state->rs.read_slice_buffer); grpc_slice_buffer_init(&stream_state->rs.read_slice_buffer); grpc_slice_buffer_stream_init(&stream_state->rs.sbs, &stream_state->rs.read_slice_buffer, 0); @@ -1185,7 +1210,7 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { *((grpc_byte_buffer**)stream_op->payload->recv_message.recv_message) = (grpc_byte_buffer*)&stream_state->rs.sbs; GRPC_CLOSURE_SCHED( - stream_op->payload->recv_message.recv_message_ready, + exec_ctx, stream_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); stream_state->state_op_done[OP_RECV_MESSAGE] = true; oas->state.state_op_done[OP_RECV_MESSAGE] = true; @@ -1229,7 +1254,8 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { (size_t)stream_state->rs.length_field); null_and_maybe_free_read_buffer(s); /* Clean up read_slice_buffer in case there is unread data. */ - grpc_slice_buffer_destroy_internal(&stream_state->rs.read_slice_buffer); + grpc_slice_buffer_destroy_internal(exec_ctx, + &stream_state->rs.read_slice_buffer); grpc_slice_buffer_init(&stream_state->rs.read_slice_buffer); grpc_slice_buffer_add(&stream_state->rs.read_slice_buffer, read_data_slice); @@ -1240,7 +1266,8 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { } *((grpc_byte_buffer**)stream_op->payload->recv_message.recv_message) = (grpc_byte_buffer*)&stream_state->rs.sbs; - GRPC_CLOSURE_SCHED(stream_op->payload->recv_message.recv_message_ready, + GRPC_CLOSURE_SCHED(exec_ctx, + stream_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); stream_state->state_op_done[OP_RECV_MESSAGE] = true; oas->state.state_op_done[OP_RECV_MESSAGE] = true; @@ -1263,7 +1290,7 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_TRAILING_METADATA", oas); if (oas->s->state.rs.trailing_metadata_valid) { grpc_chttp2_incoming_metadata_buffer_publish( - &oas->s->state.rs.trailing_metadata, + exec_ctx, &oas->s->state.rs.trailing_metadata, stream_op->payload->recv_trailing_metadata.recv_trailing_metadata); stream_state->rs.trailing_metadata_valid = false; } @@ -1288,17 +1315,17 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { op_can_be_run(stream_op, s, &oas->state, OP_ON_COMPLETE)) { CRONET_LOG(GPR_DEBUG, "running: %p OP_ON_COMPLETE", oas); if (stream_state->state_op_done[OP_CANCEL_ERROR]) { - GRPC_CLOSURE_SCHED(stream_op->on_complete, + GRPC_CLOSURE_SCHED(exec_ctx, stream_op->on_complete, GRPC_ERROR_REF(stream_state->cancel_error)); } else if (stream_state->state_callback_received[OP_FAILED]) { GRPC_CLOSURE_SCHED( - stream_op->on_complete, + exec_ctx, stream_op->on_complete, make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable.")); } else { /* All actions in this stream_op are complete. Call the on_complete * callback */ - GRPC_CLOSURE_SCHED(stream_op->on_complete, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE); } oas->state.state_op_done[OP_ON_COMPLETE] = true; oas->done = true; @@ -1323,9 +1350,9 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { Functions used by upper layers to access transport functionality. */ -static int init_stream(grpc_transport* gt, grpc_stream* gs, - grpc_stream_refcount* refcount, const void* server_data, - gpr_arena* arena) { +static int init_stream(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_stream_refcount* refcount, + const void* server_data, gpr_arena* arena) { stream_obj* s = (stream_obj*)gs; s->refcount = refcount; @@ -1356,13 +1383,15 @@ static int init_stream(grpc_transport* gt, grpc_stream* gs, return 0; } -static void set_pollset_do_nothing(grpc_transport* gt, grpc_stream* gs, - grpc_pollset* pollset) {} +static void set_pollset_do_nothing(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_pollset* pollset) {} -static void set_pollset_set_do_nothing(grpc_transport* gt, grpc_stream* gs, +static void set_pollset_set_do_nothing(grpc_exec_ctx* exec_ctx, + grpc_transport* gt, grpc_stream* gs, grpc_pollset_set* pollset_set) {} -static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, +static void perform_stream_op(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_transport_stream_op_batch* op) { CRONET_LOG(GPR_DEBUG, "perform_stream_op"); if (op->send_initial_metadata && @@ -1372,36 +1401,42 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, this field is present in metadata */ if (op->recv_initial_metadata) { GRPC_CLOSURE_SCHED( + exec_ctx, op->payload->recv_initial_metadata.recv_initial_metadata_ready, GRPC_ERROR_CANCELLED); } if (op->recv_message) { - GRPC_CLOSURE_SCHED(op->payload->recv_message.recv_message_ready, + GRPC_CLOSURE_SCHED(exec_ctx, op->payload->recv_message.recv_message_ready, GRPC_ERROR_CANCELLED); } - GRPC_CLOSURE_SCHED(op->on_complete, GRPC_ERROR_CANCELLED); + GRPC_CLOSURE_SCHED(exec_ctx, op->on_complete, GRPC_ERROR_CANCELLED); return; } stream_obj* s = (stream_obj*)gs; add_to_storage(s, op); - execute_from_storage(s); + execute_from_storage(exec_ctx, s); } -static void destroy_stream(grpc_transport* gt, grpc_stream* gs, +static void destroy_stream(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_closure* then_schedule_closure) { stream_obj* s = (stream_obj*)gs; null_and_maybe_free_read_buffer(s); /* Clean up read_slice_buffer in case there is unread data. */ - grpc_slice_buffer_destroy_internal(&s->state.rs.read_slice_buffer); + grpc_slice_buffer_destroy_internal(exec_ctx, &s->state.rs.read_slice_buffer); GRPC_ERROR_UNREF(s->state.cancel_error); - GRPC_CLOSURE_SCHED(then_schedule_closure, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE); } -static void destroy_transport(grpc_transport* gt) {} +static void destroy_transport(grpc_exec_ctx* exec_ctx, grpc_transport* gt) {} -static grpc_endpoint* get_endpoint(grpc_transport* gt) { return nullptr; } +static grpc_endpoint* get_endpoint(grpc_exec_ctx* exec_ctx, + grpc_transport* gt) { + return nullptr; +} -static void perform_op(grpc_transport* gt, grpc_transport_op* op) {} +static void perform_op(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_transport_op* op) {} static const grpc_transport_vtable grpc_cronet_vtable = { sizeof(stream_obj), diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 8dd0b7dce2..d8d753e459 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -54,8 +54,8 @@ typedef struct inproc_transport { gpr_refcount refs; bool is_client; grpc_connectivity_state_tracker connectivity; - void (*accept_stream_cb)(void* user_data, grpc_transport* transport, - const void* server_data); + void (*accept_stream_cb)(grpc_exec_ctx* exec_ctx, void* user_data, + grpc_transport* transport, const void* server_data); void* accept_stream_data; bool is_closed; struct inproc_transport* other_side; @@ -118,36 +118,39 @@ typedef struct inproc_stream { } inproc_stream; static grpc_closure do_nothing_closure; -static bool cancel_stream_locked(inproc_stream* s, grpc_error* error); -static void op_state_machine(void* arg, grpc_error* error); +static bool cancel_stream_locked(grpc_exec_ctx* exec_ctx, inproc_stream* s, + grpc_error* error); +static void op_state_machine(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error); static void ref_transport(inproc_transport* t) { INPROC_LOG(GPR_DEBUG, "ref_transport %p", t); gpr_ref(&t->refs); } -static void really_destroy_transport(inproc_transport* t) { +static void really_destroy_transport(grpc_exec_ctx* exec_ctx, + inproc_transport* t) { INPROC_LOG(GPR_DEBUG, "really_destroy_transport %p", t); - grpc_connectivity_state_destroy(&t->connectivity); + grpc_connectivity_state_destroy(exec_ctx, &t->connectivity); if (gpr_unref(&t->mu->refs)) { gpr_free(t->mu); } gpr_free(t); } -static void unref_transport(inproc_transport* t) { +static void unref_transport(grpc_exec_ctx* exec_ctx, inproc_transport* t) { INPROC_LOG(GPR_DEBUG, "unref_transport %p", t); if (gpr_unref(&t->refs)) { - really_destroy_transport(t); + really_destroy_transport(exec_ctx, t); } } #ifndef NDEBUG #define STREAM_REF(refs, reason) grpc_stream_ref(refs, reason) -#define STREAM_UNREF(refs, reason) grpc_stream_unref(refs, reason) +#define STREAM_UNREF(e, refs, reason) grpc_stream_unref(e, refs, reason) #else #define STREAM_REF(refs, reason) grpc_stream_ref(refs) -#define STREAM_UNREF(refs, reason) grpc_stream_unref(refs) +#define STREAM_UNREF(e, refs, reason) grpc_stream_unref(e, refs) #endif static void ref_stream(inproc_stream* s, const char* reason) { @@ -155,12 +158,13 @@ static void ref_stream(inproc_stream* s, const char* reason) { STREAM_REF(s->refs, reason); } -static void unref_stream(inproc_stream* s, const char* reason) { +static void unref_stream(grpc_exec_ctx* exec_ctx, inproc_stream* s, + const char* reason) { INPROC_LOG(GPR_DEBUG, "unref_stream %p %s", s, reason); - STREAM_UNREF(s->refs, reason); + STREAM_UNREF(exec_ctx, s->refs, reason); } -static void really_destroy_stream(inproc_stream* s) { +static void really_destroy_stream(grpc_exec_ctx* exec_ctx, inproc_stream* s) { INPROC_LOG(GPR_DEBUG, "really_destroy_stream %p", s); GRPC_ERROR_UNREF(s->write_buffer_cancel_error); @@ -168,13 +172,13 @@ static void really_destroy_stream(inproc_stream* s) { GRPC_ERROR_UNREF(s->cancel_other_error); if (s->recv_inited) { - grpc_slice_buffer_destroy_internal(&s->recv_message); + grpc_slice_buffer_destroy_internal(exec_ctx, &s->recv_message); } - unref_transport(s->t); + unref_transport(exec_ctx, s->t); if (s->closure_at_destroy) { - GRPC_CLOSURE_SCHED(s->closure_at_destroy, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(exec_ctx, s->closure_at_destroy, GRPC_ERROR_NONE); } } @@ -191,7 +195,7 @@ static void log_metadata(const grpc_metadata_batch* md_batch, bool is_client, } } -static grpc_error* fill_in_metadata(inproc_stream* s, +static grpc_error* fill_in_metadata(grpc_exec_ctx* exec_ctx, inproc_stream* s, const grpc_metadata_batch* metadata, uint32_t flags, grpc_metadata_batch* out_md, uint32_t* outflags, bool* markfilled) { @@ -210,18 +214,18 @@ static grpc_error* fill_in_metadata(inproc_stream* s, (elem != nullptr) && (error == GRPC_ERROR_NONE); elem = elem->next) { grpc_linked_mdelem* nelem = (grpc_linked_mdelem*)gpr_arena_alloc(s->arena, sizeof(*nelem)); - nelem->md = - grpc_mdelem_from_slices(grpc_slice_intern(GRPC_MDKEY(elem->md)), - grpc_slice_intern(GRPC_MDVALUE(elem->md))); + nelem->md = grpc_mdelem_from_slices( + exec_ctx, grpc_slice_intern(GRPC_MDKEY(elem->md)), + grpc_slice_intern(GRPC_MDVALUE(elem->md))); - error = grpc_metadata_batch_link_tail(out_md, nelem); + error = grpc_metadata_batch_link_tail(exec_ctx, out_md, nelem); } return error; } -static int init_stream(grpc_transport* gt, grpc_stream* gs, - grpc_stream_refcount* refcount, const void* server_data, - gpr_arena* arena) { +static int init_stream(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_stream_refcount* refcount, + const void* server_data, gpr_arena* arena) { INPROC_LOG(GPR_DEBUG, "init_stream %p %p %p", gt, gs, server_data); inproc_transport* t = (inproc_transport*)gt; inproc_stream* s = (inproc_stream*)gs; @@ -281,7 +285,8 @@ static int init_stream(grpc_transport* gt, grpc_stream* gs, // side to avoid destruction INPROC_LOG(GPR_DEBUG, "calling accept stream cb %p %p", st->accept_stream_cb, st->accept_stream_data); - (*st->accept_stream_cb)(st->accept_stream_data, &st->base, (void*)s); + (*st->accept_stream_cb)(exec_ctx, st->accept_stream_data, &st->base, + (void*)s); } else { // This is the server-side and is being called through accept_stream_cb inproc_stream* cs = (inproc_stream*)server_data; @@ -296,19 +301,19 @@ static int init_stream(grpc_transport* gt, grpc_stream* gs, // Now transfer from the other side's write_buffer if any to the to_read // buffer if (cs->write_buffer_initial_md_filled) { - fill_in_metadata(s, &cs->write_buffer_initial_md, + fill_in_metadata(exec_ctx, s, &cs->write_buffer_initial_md, cs->write_buffer_initial_md_flags, &s->to_read_initial_md, &s->to_read_initial_md_flags, &s->to_read_initial_md_filled); s->deadline = GPR_MIN(s->deadline, cs->write_buffer_deadline); - grpc_metadata_batch_clear(&cs->write_buffer_initial_md); + grpc_metadata_batch_clear(exec_ctx, &cs->write_buffer_initial_md); cs->write_buffer_initial_md_filled = false; } if (cs->write_buffer_trailing_md_filled) { - fill_in_metadata(s, &cs->write_buffer_trailing_md, 0, + fill_in_metadata(exec_ctx, s, &cs->write_buffer_trailing_md, 0, &s->to_read_trailing_md, nullptr, &s->to_read_trailing_md_filled); - grpc_metadata_batch_clear(&cs->write_buffer_trailing_md); + grpc_metadata_batch_clear(exec_ctx, &cs->write_buffer_trailing_md); cs->write_buffer_trailing_md_filled = false; } if (cs->write_buffer_cancel_error != GRPC_ERROR_NONE) { @@ -321,11 +326,11 @@ static int init_stream(grpc_transport* gt, grpc_stream* gs, return 0; // return value is not important } -static void close_stream_locked(inproc_stream* s) { +static void close_stream_locked(grpc_exec_ctx* exec_ctx, inproc_stream* s) { if (!s->closed) { // Release the metadata that we would have written out - grpc_metadata_batch_destroy(&s->write_buffer_initial_md); - grpc_metadata_batch_destroy(&s->write_buffer_trailing_md); + grpc_metadata_batch_destroy(exec_ctx, &s->write_buffer_initial_md); + grpc_metadata_batch_destroy(exec_ctx, &s->write_buffer_trailing_md); if (s->listed) { inproc_stream* p = s->stream_list_prev; @@ -339,21 +344,22 @@ static void close_stream_locked(inproc_stream* s) { n->stream_list_prev = p; } s->listed = false; - unref_stream(s, "close_stream:list"); + unref_stream(exec_ctx, s, "close_stream:list"); } s->closed = true; - unref_stream(s, "close_stream:closing"); + unref_stream(exec_ctx, s, "close_stream:closing"); } } // This function means that we are done talking/listening to the other side -static void close_other_side_locked(inproc_stream* s, const char* reason) { +static void close_other_side_locked(grpc_exec_ctx* exec_ctx, inproc_stream* s, + const char* reason) { if (s->other_side != nullptr) { // First release the metadata that came from the other side's arena - grpc_metadata_batch_destroy(&s->to_read_initial_md); - grpc_metadata_batch_destroy(&s->to_read_trailing_md); + grpc_metadata_batch_destroy(exec_ctx, &s->to_read_initial_md); + grpc_metadata_batch_destroy(exec_ctx, &s->to_read_trailing_md); - unref_stream(s->other_side, reason); + unref_stream(exec_ctx, s->other_side, reason); s->other_side_closed = true; s->other_side = nullptr; } else if (!s->other_side_closed) { @@ -365,7 +371,8 @@ static void close_other_side_locked(inproc_stream* s, const char* reason) { // this stream_op_batch is only one of the pending operations for this // stream. This is called when one of the pending operations for the stream // is done and about to be NULLed out -static void complete_if_batch_end_locked(inproc_stream* s, grpc_error* error, +static void complete_if_batch_end_locked(grpc_exec_ctx* exec_ctx, + inproc_stream* s, grpc_error* error, grpc_transport_stream_op_batch* op, const char* msg) { int is_sm = (int)(op == s->send_message_op); @@ -376,20 +383,22 @@ static void complete_if_batch_end_locked(inproc_stream* s, grpc_error* error, if ((is_sm + is_stm + is_rim + is_rm + is_rtm) == 1) { INPROC_LOG(GPR_DEBUG, "%s %p %p %p", msg, s, op, error); - GRPC_CLOSURE_SCHED(op->on_complete, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(exec_ctx, op->on_complete, GRPC_ERROR_REF(error)); } } -static void maybe_schedule_op_closure_locked(inproc_stream* s, +static void maybe_schedule_op_closure_locked(grpc_exec_ctx* exec_ctx, + inproc_stream* s, grpc_error* error) { if (s && s->ops_needed && !s->op_closure_scheduled) { - GRPC_CLOSURE_SCHED(&s->op_closure, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(exec_ctx, &s->op_closure, GRPC_ERROR_REF(error)); s->op_closure_scheduled = true; s->ops_needed = false; } } -static void fail_helper_locked(inproc_stream* s, grpc_error* error) { +static void fail_helper_locked(grpc_exec_ctx* exec_ctx, inproc_stream* s, + grpc_error* error) { INPROC_LOG(GPR_DEBUG, "op_state_machine %p fail_helper", s); // If we're failing this side, we need to make sure that // we also send or have already sent trailing metadata @@ -406,14 +415,14 @@ static void fail_helper_locked(inproc_stream* s, grpc_error* error) { : &other->to_read_trailing_md; bool* destfilled = (other == nullptr) ? &s->write_buffer_trailing_md_filled : &other->to_read_trailing_md_filled; - fill_in_metadata(s, &fake_md, 0, dest, nullptr, destfilled); - grpc_metadata_batch_destroy(&fake_md); + fill_in_metadata(exec_ctx, s, &fake_md, 0, dest, nullptr, destfilled); + grpc_metadata_batch_destroy(exec_ctx, &fake_md); if (other != nullptr) { if (other->cancel_other_error == GRPC_ERROR_NONE) { other->cancel_other_error = GRPC_ERROR_REF(error); } - maybe_schedule_op_closure_locked(other, error); + maybe_schedule_op_closure_locked(exec_ctx, other, error); } else if (s->write_buffer_cancel_error == GRPC_ERROR_NONE) { s->write_buffer_cancel_error = GRPC_ERROR_REF(error); } @@ -427,22 +436,24 @@ static void fail_helper_locked(inproc_stream* s, grpc_error* error) { grpc_metadata_batch_init(&fake_md); grpc_linked_mdelem* path_md = (grpc_linked_mdelem*)gpr_arena_alloc(s->arena, sizeof(*path_md)); - path_md->md = grpc_mdelem_from_slices(g_fake_path_key, g_fake_path_value); - GPR_ASSERT(grpc_metadata_batch_link_tail(&fake_md, path_md) == + path_md->md = + grpc_mdelem_from_slices(exec_ctx, g_fake_path_key, g_fake_path_value); + GPR_ASSERT(grpc_metadata_batch_link_tail(exec_ctx, &fake_md, path_md) == GRPC_ERROR_NONE); grpc_linked_mdelem* auth_md = (grpc_linked_mdelem*)gpr_arena_alloc(s->arena, sizeof(*auth_md)); - auth_md->md = grpc_mdelem_from_slices(g_fake_auth_key, g_fake_auth_value); - GPR_ASSERT(grpc_metadata_batch_link_tail(&fake_md, auth_md) == + auth_md->md = + grpc_mdelem_from_slices(exec_ctx, g_fake_auth_key, g_fake_auth_value); + GPR_ASSERT(grpc_metadata_batch_link_tail(exec_ctx, &fake_md, auth_md) == GRPC_ERROR_NONE); fill_in_metadata( - s, &fake_md, 0, + exec_ctx, s, &fake_md, 0, s->recv_initial_md_op->payload->recv_initial_metadata .recv_initial_metadata, s->recv_initial_md_op->payload->recv_initial_metadata.recv_flags, nullptr); - grpc_metadata_batch_destroy(&fake_md); + grpc_metadata_batch_destroy(exec_ctx, &fake_md); err = GRPC_ERROR_NONE; } else { err = GRPC_ERROR_REF(error); @@ -458,13 +469,14 @@ static void fail_helper_locked(inproc_stream* s, grpc_error* error) { INPROC_LOG(GPR_DEBUG, "fail_helper %p scheduling initial-metadata-ready %p %p", s, error, err); - GRPC_CLOSURE_SCHED(s->recv_initial_md_op->payload->recv_initial_metadata + GRPC_CLOSURE_SCHED(exec_ctx, + s->recv_initial_md_op->payload->recv_initial_metadata .recv_initial_metadata_ready, err); // Last use of err so no need to REF and then UNREF it complete_if_batch_end_locked( - s, error, s->recv_initial_md_op, + exec_ctx, s, error, s->recv_initial_md_op, "fail_helper scheduling recv-initial-metadata-on-complete"); s->recv_initial_md_op = nullptr; } @@ -472,22 +484,22 @@ static void fail_helper_locked(inproc_stream* s, grpc_error* error) { INPROC_LOG(GPR_DEBUG, "fail_helper %p scheduling message-ready %p", s, error); GRPC_CLOSURE_SCHED( - s->recv_message_op->payload->recv_message.recv_message_ready, + exec_ctx, s->recv_message_op->payload->recv_message.recv_message_ready, GRPC_ERROR_REF(error)); complete_if_batch_end_locked( - s, error, s->recv_message_op, + exec_ctx, s, error, s->recv_message_op, "fail_helper scheduling recv-message-on-complete"); s->recv_message_op = nullptr; } if (s->send_message_op) { complete_if_batch_end_locked( - s, error, s->send_message_op, + exec_ctx, s, error, s->send_message_op, "fail_helper scheduling send-message-on-complete"); s->send_message_op = nullptr; } if (s->send_trailing_md_op) { complete_if_batch_end_locked( - s, error, s->send_trailing_md_op, + exec_ctx, s, error, s->send_trailing_md_op, "fail_helper scheduling send-trailng-md-on-complete"); s->send_trailing_md_op = nullptr; } @@ -496,22 +508,23 @@ static void fail_helper_locked(inproc_stream* s, grpc_error* error) { "fail_helper %p scheduling trailing-md-on-complete %p", s, error); complete_if_batch_end_locked( - s, error, s->recv_trailing_md_op, + exec_ctx, s, error, s->recv_trailing_md_op, "fail_helper scheduling recv-trailing-metadata-on-complete"); s->recv_trailing_md_op = nullptr; } - close_other_side_locked(s, "fail_helper:other_side"); - close_stream_locked(s); + close_other_side_locked(exec_ctx, s, "fail_helper:other_side"); + close_stream_locked(exec_ctx, s); GRPC_ERROR_UNREF(error); } -static void message_transfer_locked(inproc_stream* sender, +static void message_transfer_locked(grpc_exec_ctx* exec_ctx, + inproc_stream* sender, inproc_stream* receiver) { size_t remaining = sender->send_message_op->payload->send_message.send_message->length; if (receiver->recv_inited) { - grpc_slice_buffer_destroy_internal(&receiver->recv_message); + grpc_slice_buffer_destroy_internal(exec_ctx, &receiver->recv_message); } grpc_slice_buffer_init(&receiver->recv_message); receiver->recv_inited = true; @@ -519,13 +532,13 @@ static void message_transfer_locked(inproc_stream* sender, grpc_slice message_slice; grpc_closure unused; GPR_ASSERT(grpc_byte_stream_next( - sender->send_message_op->payload->send_message.send_message, SIZE_MAX, - &unused)); + exec_ctx, sender->send_message_op->payload->send_message.send_message, + SIZE_MAX, &unused)); grpc_error* error = grpc_byte_stream_pull( - sender->send_message_op->payload->send_message.send_message, + exec_ctx, sender->send_message_op->payload->send_message.send_message, &message_slice); if (error != GRPC_ERROR_NONE) { - cancel_stream_locked(sender, GRPC_ERROR_REF(error)); + cancel_stream_locked(exec_ctx, sender, GRPC_ERROR_REF(error)); break; } GPR_ASSERT(error == GRPC_ERROR_NONE); @@ -540,20 +553,22 @@ static void message_transfer_locked(inproc_stream* sender, INPROC_LOG(GPR_DEBUG, "message_transfer_locked %p scheduling message-ready", receiver); GRPC_CLOSURE_SCHED( + exec_ctx, receiver->recv_message_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); complete_if_batch_end_locked( - sender, GRPC_ERROR_NONE, sender->send_message_op, + exec_ctx, sender, GRPC_ERROR_NONE, sender->send_message_op, "message_transfer scheduling sender on_complete"); complete_if_batch_end_locked( - receiver, GRPC_ERROR_NONE, receiver->recv_message_op, + exec_ctx, receiver, GRPC_ERROR_NONE, receiver->recv_message_op, "message_transfer scheduling receiver on_complete"); receiver->recv_message_op = nullptr; sender->send_message_op = nullptr; } -static void op_state_machine(void* arg, grpc_error* error) { +static void op_state_machine(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { // This function gets called when we have contents in the unprocessed reads // Get what we want based on our ops wanted // Schedule our appropriate closures @@ -574,26 +589,26 @@ static void op_state_machine(void* arg, grpc_error* error) { inproc_stream* other = s->other_side; if (s->cancel_self_error != GRPC_ERROR_NONE) { - fail_helper_locked(s, GRPC_ERROR_REF(s->cancel_self_error)); + fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(s->cancel_self_error)); goto done; } else if (s->cancel_other_error != GRPC_ERROR_NONE) { - fail_helper_locked(s, GRPC_ERROR_REF(s->cancel_other_error)); + fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(s->cancel_other_error)); goto done; } else if (error != GRPC_ERROR_NONE) { - fail_helper_locked(s, GRPC_ERROR_REF(error)); + fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(error)); goto done; } if (s->send_message_op && other) { if (other->recv_message_op) { - message_transfer_locked(s, other); - maybe_schedule_op_closure_locked(other, GRPC_ERROR_NONE); + message_transfer_locked(exec_ctx, s, other); + maybe_schedule_op_closure_locked(exec_ctx, other, GRPC_ERROR_NONE); } else if (!s->t->is_client && (s->trailing_md_sent || other->recv_trailing_md_op)) { // A server send will never be matched if the client is waiting // for trailing metadata already complete_if_batch_end_locked( - s, GRPC_ERROR_NONE, s->send_message_op, + exec_ctx, s, GRPC_ERROR_NONE, s->send_message_op, "op_state_machine scheduling send-message-on-complete"); s->send_message_op = nullptr; } @@ -615,11 +630,11 @@ static void op_state_machine(void* arg, grpc_error* error) { // The buffer is already in use; that's an error! INPROC_LOG(GPR_DEBUG, "Extra trailing metadata %p", s); new_err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Extra trailing metadata"); - fail_helper_locked(s, GRPC_ERROR_REF(new_err)); + fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); goto done; } else { if (!other || !other->closed) { - fill_in_metadata(s, + fill_in_metadata(exec_ctx, s, s->send_trailing_md_op->payload->send_trailing_metadata .send_trailing_metadata, 0, dest, nullptr, destfilled); @@ -628,15 +643,15 @@ static void op_state_machine(void* arg, grpc_error* error) { if (!s->t->is_client && s->trailing_md_recvd && s->recv_trailing_md_op) { INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling trailing-md-on-complete", s); - GRPC_CLOSURE_SCHED(s->recv_trailing_md_op->on_complete, + GRPC_CLOSURE_SCHED(exec_ctx, s->recv_trailing_md_op->on_complete, GRPC_ERROR_NONE); s->recv_trailing_md_op = nullptr; needs_close = true; } } - maybe_schedule_op_closure_locked(other, GRPC_ERROR_NONE); + maybe_schedule_op_closure_locked(exec_ctx, other, GRPC_ERROR_NONE); complete_if_batch_end_locked( - s, GRPC_ERROR_NONE, s->send_trailing_md_op, + exec_ctx, s, GRPC_ERROR_NONE, s->send_trailing_md_op, "op_state_machine scheduling send-trailing-metadata-on-complete"); s->send_trailing_md_op = nullptr; } @@ -649,14 +664,14 @@ static void op_state_machine(void* arg, grpc_error* error) { "op_state_machine %p scheduling on_complete errors for already " "recvd initial md %p", s, new_err); - fail_helper_locked(s, GRPC_ERROR_REF(new_err)); + fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); goto done; } if (s->to_read_initial_md_filled) { s->initial_md_recvd = true; new_err = fill_in_metadata( - s, &s->to_read_initial_md, s->to_read_initial_md_flags, + exec_ctx, s, &s->to_read_initial_md, s->to_read_initial_md_flags, s->recv_initial_md_op->payload->recv_initial_metadata .recv_initial_metadata, s->recv_initial_md_op->payload->recv_initial_metadata.recv_flags, @@ -669,16 +684,17 @@ static void op_state_machine(void* arg, grpc_error* error) { .trailing_metadata_available = (other != nullptr && other->send_trailing_md_op != nullptr); } - grpc_metadata_batch_clear(&s->to_read_initial_md); + grpc_metadata_batch_clear(exec_ctx, &s->to_read_initial_md); s->to_read_initial_md_filled = false; INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling initial-metadata-ready %p", s, new_err); - GRPC_CLOSURE_SCHED(s->recv_initial_md_op->payload->recv_initial_metadata + GRPC_CLOSURE_SCHED(exec_ctx, + s->recv_initial_md_op->payload->recv_initial_metadata .recv_initial_metadata_ready, GRPC_ERROR_REF(new_err)); complete_if_batch_end_locked( - s, new_err, s->recv_initial_md_op, + exec_ctx, s, new_err, s->recv_initial_md_op, "op_state_machine scheduling recv-initial-metadata-on-complete"); s->recv_initial_md_op = nullptr; @@ -686,20 +702,20 @@ static void op_state_machine(void* arg, grpc_error* error) { INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling on_complete errors2 %p", s, new_err); - fail_helper_locked(s, GRPC_ERROR_REF(new_err)); + fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); goto done; } } } if (s->recv_message_op) { if (other && other->send_message_op) { - message_transfer_locked(other, s); - maybe_schedule_op_closure_locked(other, GRPC_ERROR_NONE); + message_transfer_locked(exec_ctx, other, s); + maybe_schedule_op_closure_locked(exec_ctx, other, GRPC_ERROR_NONE); } } if (s->recv_trailing_md_op && s->t->is_client && other && other->send_message_op) { - maybe_schedule_op_closure_locked(other, GRPC_ERROR_NONE); + maybe_schedule_op_closure_locked(exec_ctx, other, GRPC_ERROR_NONE); } if (s->to_read_trailing_md_filled) { if (s->trailing_md_recvd) { @@ -710,7 +726,7 @@ static void op_state_machine(void* arg, grpc_error* error) { "op_state_machine %p scheduling on_complete errors for already " "recvd trailing md %p", s, new_err); - fail_helper_locked(s, GRPC_ERROR_REF(new_err)); + fail_helper_locked(exec_ctx, s, GRPC_ERROR_REF(new_err)); goto done; } if (s->recv_message_op != nullptr) { @@ -718,10 +734,11 @@ static void op_state_machine(void* arg, grpc_error* error) { // satisfied INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling message-ready", s); GRPC_CLOSURE_SCHED( + exec_ctx, s->recv_message_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); complete_if_batch_end_locked( - s, new_err, s->recv_message_op, + exec_ctx, s, new_err, s->recv_message_op, "op_state_machine scheduling recv-message-on-complete"); s->recv_message_op = nullptr; } @@ -729,7 +746,7 @@ static void op_state_machine(void* arg, grpc_error* error) { // Nothing further will try to receive from this stream, so finish off // any outstanding send_message op complete_if_batch_end_locked( - s, new_err, s->send_message_op, + exec_ctx, s, new_err, s->send_message_op, "op_state_machine scheduling send-message-on-complete"); s->send_message_op = nullptr; } @@ -737,11 +754,11 @@ static void op_state_machine(void* arg, grpc_error* error) { // We wanted trailing metadata and we got it s->trailing_md_recvd = true; new_err = - fill_in_metadata(s, &s->to_read_trailing_md, 0, + fill_in_metadata(exec_ctx, s, &s->to_read_trailing_md, 0, s->recv_trailing_md_op->payload ->recv_trailing_metadata.recv_trailing_metadata, nullptr, nullptr); - grpc_metadata_batch_clear(&s->to_read_trailing_md); + grpc_metadata_batch_clear(exec_ctx, &s->to_read_trailing_md); s->to_read_trailing_md_filled = false; // We should schedule the recv_trailing_md_op completion if @@ -753,7 +770,7 @@ static void op_state_machine(void* arg, grpc_error* error) { INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling trailing-md-on-complete %p", s, new_err); - GRPC_CLOSURE_SCHED(s->recv_trailing_md_op->on_complete, + GRPC_CLOSURE_SCHED(exec_ctx, s->recv_trailing_md_op->on_complete, GRPC_ERROR_REF(new_err)); s->recv_trailing_md_op = nullptr; needs_close = true; @@ -774,10 +791,10 @@ static void op_state_machine(void* arg, grpc_error* error) { // recv_message_op INPROC_LOG(GPR_DEBUG, "op_state_machine %p scheduling message-ready", s); GRPC_CLOSURE_SCHED( - s->recv_message_op->payload->recv_message.recv_message_ready, + exec_ctx, s->recv_message_op->payload->recv_message.recv_message_ready, GRPC_ERROR_NONE); complete_if_batch_end_locked( - s, new_err, s->recv_message_op, + exec_ctx, s, new_err, s->recv_message_op, "op_state_machine scheduling recv-message-on-complete"); s->recv_message_op = nullptr; } @@ -786,7 +803,7 @@ static void op_state_machine(void* arg, grpc_error* error) { // Nothing further will try to receive from this stream, so finish off // any outstanding send_message op complete_if_batch_end_locked( - s, new_err, s->send_message_op, + exec_ctx, s, new_err, s->send_message_op, "op_state_machine scheduling send-message-on-complete"); s->send_message_op = nullptr; } @@ -802,21 +819,22 @@ static void op_state_machine(void* arg, grpc_error* error) { } done: if (needs_close) { - close_other_side_locked(s, "op_state_machine"); - close_stream_locked(s); + close_other_side_locked(exec_ctx, s, "op_state_machine"); + close_stream_locked(exec_ctx, s); } gpr_mu_unlock(mu); GRPC_ERROR_UNREF(new_err); } -static bool cancel_stream_locked(inproc_stream* s, grpc_error* error) { +static bool cancel_stream_locked(grpc_exec_ctx* exec_ctx, inproc_stream* s, + grpc_error* error) { bool ret = false; // was the cancel accepted INPROC_LOG(GPR_DEBUG, "cancel_stream %p with %s", s, grpc_error_string(error)); if (s->cancel_self_error == GRPC_ERROR_NONE) { ret = true; s->cancel_self_error = GRPC_ERROR_REF(error); - maybe_schedule_op_closure_locked(s, s->cancel_self_error); + maybe_schedule_op_closure_locked(exec_ctx, s, s->cancel_self_error); // Send trailing md to the other side indicating cancellation, even if we // already have s->trailing_md_sent = true; @@ -830,14 +848,15 @@ static bool cancel_stream_locked(inproc_stream* s, grpc_error* error) { : &other->to_read_trailing_md; bool* destfilled = (other == nullptr) ? &s->write_buffer_trailing_md_filled : &other->to_read_trailing_md_filled; - fill_in_metadata(s, &cancel_md, 0, dest, nullptr, destfilled); - grpc_metadata_batch_destroy(&cancel_md); + fill_in_metadata(exec_ctx, s, &cancel_md, 0, dest, nullptr, destfilled); + grpc_metadata_batch_destroy(exec_ctx, &cancel_md); if (other != nullptr) { if (other->cancel_other_error == GRPC_ERROR_NONE) { other->cancel_other_error = GRPC_ERROR_REF(s->cancel_self_error); } - maybe_schedule_op_closure_locked(other, other->cancel_other_error); + maybe_schedule_op_closure_locked(exec_ctx, other, + other->cancel_other_error); } else if (s->write_buffer_cancel_error == GRPC_ERROR_NONE) { s->write_buffer_cancel_error = GRPC_ERROR_REF(s->cancel_self_error); } @@ -847,20 +866,21 @@ static bool cancel_stream_locked(inproc_stream* s, grpc_error* error) { // md, now's the chance if (!s->t->is_client && s->trailing_md_recvd && s->recv_trailing_md_op) { complete_if_batch_end_locked( - s, s->cancel_self_error, s->recv_trailing_md_op, + exec_ctx, s, s->cancel_self_error, s->recv_trailing_md_op, "cancel_stream scheduling trailing-md-on-complete"); s->recv_trailing_md_op = nullptr; } } - close_other_side_locked(s, "cancel_stream:other_side"); - close_stream_locked(s); + close_other_side_locked(exec_ctx, s, "cancel_stream:other_side"); + close_stream_locked(exec_ctx, s); GRPC_ERROR_UNREF(error); return ret; } -static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, +static void perform_stream_op(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_transport_stream_op_batch* op) { INPROC_LOG(GPR_DEBUG, "perform_stream_op %p %p %p", gt, gs, op); inproc_stream* s = (inproc_stream*)gs; @@ -886,7 +906,7 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, if (op->cancel_stream) { // Call cancel_stream_locked without ref'ing the cancel_error because // this function is responsible to make sure that that field gets unref'ed - cancel_stream_locked(s, op->payload->cancel_stream.cancel_error); + cancel_stream_locked(exec_ctx, s, op->payload->cancel_stream.cancel_error); // this op can complete without an error } else if (s->cancel_self_error != GRPC_ERROR_NONE) { // already self-canceled so still give it an error @@ -926,7 +946,8 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, } else { if (!other || !other->closed) { fill_in_metadata( - s, op->payload->send_initial_metadata.send_initial_metadata, + exec_ctx, s, + op->payload->send_initial_metadata.send_initial_metadata, op->payload->send_initial_metadata.send_initial_metadata_flags, dest, destflags, destfilled); } @@ -938,7 +959,7 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, s->initial_md_sent = true; } } - maybe_schedule_op_closure_locked(other, error); + maybe_schedule_op_closure_locked(exec_ctx, other, error); } } @@ -978,7 +999,7 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, (op->recv_message && other && (other->send_message_op != nullptr)) || (s->to_read_trailing_md_filled || s->trailing_md_recvd)) { if (!s->op_closure_scheduled) { - GRPC_CLOSURE_SCHED(&s->op_closure, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(exec_ctx, &s->op_closure, GRPC_ERROR_NONE); s->op_closure_scheduled = true; } } else { @@ -1002,6 +1023,7 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, "perform_stream_op error %p scheduling initial-metadata-ready %p", s, error); GRPC_CLOSURE_SCHED( + exec_ctx, op->payload->recv_initial_metadata.recv_initial_metadata_ready, GRPC_ERROR_REF(error)); } @@ -1010,26 +1032,28 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, GPR_DEBUG, "perform_stream_op error %p scheduling recv message-ready %p", s, error); - GRPC_CLOSURE_SCHED(op->payload->recv_message.recv_message_ready, + GRPC_CLOSURE_SCHED(exec_ctx, + op->payload->recv_message.recv_message_ready, GRPC_ERROR_REF(error)); } } INPROC_LOG(GPR_DEBUG, "perform_stream_op %p scheduling on_complete %p", s, error); - GRPC_CLOSURE_SCHED(on_complete, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(exec_ctx, on_complete, GRPC_ERROR_REF(error)); } if (needs_close) { - close_other_side_locked(s, "perform_stream_op:other_side"); - close_stream_locked(s); + close_other_side_locked(exec_ctx, s, "perform_stream_op:other_side"); + close_stream_locked(exec_ctx, s); } gpr_mu_unlock(mu); GRPC_ERROR_UNREF(error); } -static void close_transport_locked(inproc_transport* t) { +static void close_transport_locked(grpc_exec_ctx* exec_ctx, + inproc_transport* t) { INPROC_LOG(GPR_DEBUG, "close_transport %p %d", t, t->is_closed); grpc_connectivity_state_set( - &t->connectivity, GRPC_CHANNEL_SHUTDOWN, + exec_ctx, &t->connectivity, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Closing transport."), "close transport"); if (!t->is_closed) { @@ -1038,7 +1062,7 @@ static void close_transport_locked(inproc_transport* t) { while (t->stream_list != nullptr) { // cancel_stream_locked also adjusts stream list cancel_stream_locked( - t->stream_list, + exec_ctx, t->stream_list, grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport closed"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); @@ -1046,13 +1070,14 @@ static void close_transport_locked(inproc_transport* t) { } } -static void perform_transport_op(grpc_transport* gt, grpc_transport_op* op) { +static void perform_transport_op(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_transport_op* op) { inproc_transport* t = (inproc_transport*)gt; INPROC_LOG(GPR_DEBUG, "perform_transport_op %p %p", t, op); gpr_mu_lock(&t->mu->mu); if (op->on_connectivity_state_change) { grpc_connectivity_state_notify_on_state_change( - &t->connectivity, op->connectivity_state, + exec_ctx, &t->connectivity, op->connectivity_state, op->on_connectivity_state_change); } if (op->set_accept_stream) { @@ -1060,7 +1085,7 @@ static void perform_transport_op(grpc_transport* gt, grpc_transport_op* op) { t->accept_stream_data = op->set_accept_stream_user_data; } if (op->on_consumed) { - GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(exec_ctx, op->on_consumed, GRPC_ERROR_NONE); } bool do_close = false; @@ -1074,67 +1099,71 @@ static void perform_transport_op(grpc_transport* gt, grpc_transport_op* op) { } if (do_close) { - close_transport_locked(t); + close_transport_locked(exec_ctx, t); } gpr_mu_unlock(&t->mu->mu); } -static void destroy_stream(grpc_transport* gt, grpc_stream* gs, +static void destroy_stream(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_closure* then_schedule_closure) { INPROC_LOG(GPR_DEBUG, "destroy_stream %p %p", gs, then_schedule_closure); inproc_stream* s = (inproc_stream*)gs; s->closure_at_destroy = then_schedule_closure; - really_destroy_stream(s); + really_destroy_stream(exec_ctx, s); } -static void destroy_transport(grpc_transport* gt) { +static void destroy_transport(grpc_exec_ctx* exec_ctx, grpc_transport* gt) { inproc_transport* t = (inproc_transport*)gt; INPROC_LOG(GPR_DEBUG, "destroy_transport %p", t); gpr_mu_lock(&t->mu->mu); - close_transport_locked(t); + close_transport_locked(exec_ctx, t); gpr_mu_unlock(&t->mu->mu); - unref_transport(t->other_side); - unref_transport(t); + unref_transport(exec_ctx, t->other_side); + unref_transport(exec_ctx, t); } /******************************************************************************* * INTEGRATION GLUE */ -static void set_pollset(grpc_transport* gt, grpc_stream* gs, - grpc_pollset* pollset) { +static void set_pollset(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_pollset* pollset) { // Nothing to do here } -static void set_pollset_set(grpc_transport* gt, grpc_stream* gs, - grpc_pollset_set* pollset_set) { +static void set_pollset_set(grpc_exec_ctx* exec_ctx, grpc_transport* gt, + grpc_stream* gs, grpc_pollset_set* pollset_set) { // Nothing to do here } -static grpc_endpoint* get_endpoint(grpc_transport* t) { return nullptr; } +static grpc_endpoint* get_endpoint(grpc_exec_ctx* exec_ctx, grpc_transport* t) { + return nullptr; +} /******************************************************************************* * GLOBAL INIT AND DESTROY */ -static void do_nothing(void* arg, grpc_error* error) {} +static void do_nothing(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {} void grpc_inproc_transport_init(void) { - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_CLOSURE_INIT(&do_nothing_closure, do_nothing, nullptr, grpc_schedule_on_exec_ctx); g_empty_slice = grpc_slice_from_static_buffer(nullptr, 0); grpc_slice key_tmp = grpc_slice_from_static_string(":path"); g_fake_path_key = grpc_slice_intern(key_tmp); - grpc_slice_unref_internal(key_tmp); + grpc_slice_unref_internal(&exec_ctx, key_tmp); g_fake_path_value = grpc_slice_from_static_string("/"); grpc_slice auth_tmp = grpc_slice_from_static_string(":authority"); g_fake_auth_key = grpc_slice_intern(auth_tmp); - grpc_slice_unref_internal(auth_tmp); + grpc_slice_unref_internal(&exec_ctx, auth_tmp); g_fake_auth_value = grpc_slice_from_static_string("inproc-fail"); + grpc_exec_ctx_finish(&exec_ctx); } static const grpc_transport_vtable inproc_vtable = { @@ -1146,7 +1175,8 @@ static const grpc_transport_vtable inproc_vtable = { /******************************************************************************* * Main inproc transport functions */ -static void inproc_transports_create(grpc_transport** server_transport, +static void inproc_transports_create(grpc_exec_ctx* exec_ctx, + grpc_transport** server_transport, const grpc_channel_args* server_args, grpc_transport** client_transport, const grpc_channel_args* client_args) { @@ -1183,7 +1213,7 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server, GRPC_API_TRACE("grpc_inproc_channel_create(server=%p, args=%p)", 2, (server, args)); - grpc_core::ExecCtx exec_ctx; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const grpc_channel_args* server_args = grpc_server_get_channel_args(server); @@ -1198,26 +1228,30 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server, grpc_transport* server_transport; grpc_transport* client_transport; - inproc_transports_create(&server_transport, server_args, &client_transport, - client_args); + inproc_transports_create(&exec_ctx, &server_transport, server_args, + &client_transport, client_args); - grpc_server_setup_transport(server, server_transport, nullptr, server_args); - grpc_channel* channel = grpc_channel_create( - "inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport); + grpc_server_setup_transport(&exec_ctx, server, server_transport, nullptr, + server_args); + grpc_channel* channel = + grpc_channel_create(&exec_ctx, "inproc", client_args, + GRPC_CLIENT_DIRECT_CHANNEL, client_transport); // Free up created channel args - grpc_channel_args_destroy(client_args); + grpc_channel_args_destroy(&exec_ctx, client_args); // Now finish scheduled operations + grpc_exec_ctx_finish(&exec_ctx); return channel; } void grpc_inproc_transport_shutdown(void) { - grpc_core::ExecCtx exec_ctx; - grpc_slice_unref_internal(g_empty_slice); - grpc_slice_unref_internal(g_fake_path_key); - grpc_slice_unref_internal(g_fake_path_value); - grpc_slice_unref_internal(g_fake_auth_key); - grpc_slice_unref_internal(g_fake_auth_value); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_slice_unref_internal(&exec_ctx, g_empty_slice); + grpc_slice_unref_internal(&exec_ctx, g_fake_path_key); + grpc_slice_unref_internal(&exec_ctx, g_fake_path_value); + grpc_slice_unref_internal(&exec_ctx, g_fake_auth_key); + grpc_slice_unref_internal(&exec_ctx, g_fake_auth_value); + grpc_exec_ctx_finish(&exec_ctx); } |