From 9542528fb975edb241cd7d71c5542c31f20b24a5 Mon Sep 17 00:00:00 2001 From: Eero Kurimo Date: Tue, 14 Sep 2021 12:24:39 +0300 Subject: [PATCH 1/2] Client shutdown should not need a channel --- source/client.c | 44 +++++++++++++++++++++++++++++++++ source/client_channel_handler.c | 44 --------------------------------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/source/client.c b/source/client.c index 1c72e2f8..bc8057af 100644 --- a/source/client.c +++ b/source/client.c @@ -2975,3 +2975,47 @@ int aws_mqtt_client_connection_ping(struct aws_mqtt_client_connection *connectio return (packet_id > 0) ? AWS_OP_SUCCESS : AWS_OP_ERR; } + +struct mqtt_shutdown_task { + int error_code; + struct aws_channel_task task; +}; + +static void s_mqtt_disconnect_task(struct aws_channel_task *channel_task, void *arg, enum aws_task_status status) { + + (void)status; + + struct mqtt_shutdown_task *task = AWS_CONTAINER_OF(channel_task, struct mqtt_shutdown_task, task); + struct aws_mqtt_client_connection *connection = arg; + + AWS_LOGF_TRACE(AWS_LS_MQTT_CLIENT, "id=%p: Doing disconnect", (void *)connection); + { /* BEGIN CRITICAL SECTION */ + mqtt_connection_lock_synced_data(connection); + /* If there is an outstanding reconnect task, cancel it */ + if (connection->synced_data.state == AWS_MQTT_CLIENT_STATE_DISCONNECTING && connection->reconnect_task) { + aws_atomic_store_ptr(&connection->reconnect_task->connection_ptr, NULL); + /* If the reconnect_task isn't scheduled, free it */ + if (connection->reconnect_task && !connection->reconnect_task->task.timestamp) { + aws_mem_release(connection->reconnect_task->allocator, connection->reconnect_task); + } + connection->reconnect_task = NULL; + } + mqtt_connection_unlock_synced_data(connection); + } /* END CRITICAL SECTION */ + + if (connection->slot && connection->slot->channel) { + aws_channel_shutdown(connection->slot->channel, task->error_code); + } + + aws_mem_release(connection->allocator, task); +} + +void mqtt_disconnect_impl(struct aws_mqtt_client_connection *connection, int error_code) { + if (connection->slot) { + struct mqtt_shutdown_task *shutdown_task = + aws_mem_calloc(connection->allocator, 1, sizeof(struct mqtt_shutdown_task)); + shutdown_task->error_code = error_code; + aws_channel_task_init(&shutdown_task->task, s_mqtt_disconnect_task, connection, "mqtt_disconnect"); + aws_channel_schedule_task_now(connection->slot->channel, &shutdown_task->task); + } +} diff --git a/source/client_channel_handler.c b/source/client_channel_handler.c index 25e8d31d..f1bc3f14 100644 --- a/source/client_channel_handler.c +++ b/source/client_channel_handler.c @@ -963,47 +963,3 @@ void mqtt_request_complete(struct aws_mqtt_client_connection *connection, int er on_complete(connection, packet_id, error_code, on_complete_ud); } } - -struct mqtt_shutdown_task { - int error_code; - struct aws_channel_task task; -}; - -static void s_mqtt_disconnect_task(struct aws_channel_task *channel_task, void *arg, enum aws_task_status status) { - - (void)status; - - struct mqtt_shutdown_task *task = AWS_CONTAINER_OF(channel_task, struct mqtt_shutdown_task, task); - struct aws_mqtt_client_connection *connection = arg; - - AWS_LOGF_TRACE(AWS_LS_MQTT_CLIENT, "id=%p: Doing disconnect", (void *)connection); - { /* BEGIN CRITICAL SECTION */ - mqtt_connection_lock_synced_data(connection); - /* If there is an outstanding reconnect task, cancel it */ - if (connection->synced_data.state == AWS_MQTT_CLIENT_STATE_DISCONNECTING && connection->reconnect_task) { - aws_atomic_store_ptr(&connection->reconnect_task->connection_ptr, NULL); - /* If the reconnect_task isn't scheduled, free it */ - if (connection->reconnect_task && !connection->reconnect_task->task.timestamp) { - aws_mem_release(connection->reconnect_task->allocator, connection->reconnect_task); - } - connection->reconnect_task = NULL; - } - mqtt_connection_unlock_synced_data(connection); - } /* END CRITICAL SECTION */ - - if (connection->slot && connection->slot->channel) { - aws_channel_shutdown(connection->slot->channel, task->error_code); - } - - aws_mem_release(connection->allocator, task); -} - -void mqtt_disconnect_impl(struct aws_mqtt_client_connection *connection, int error_code) { - if (connection->slot) { - struct mqtt_shutdown_task *shutdown_task = - aws_mem_calloc(connection->allocator, 1, sizeof(struct mqtt_shutdown_task)); - shutdown_task->error_code = error_code; - aws_channel_task_init(&shutdown_task->task, s_mqtt_disconnect_task, connection, "mqtt_disconnect"); - aws_channel_schedule_task_now(connection->slot->channel, &shutdown_task->task); - } -} From 468bb8952a132dadbc39d454b0f864bf97f7c7e8 Mon Sep 17 00:00:00 2001 From: Eero Kurimo Date: Tue, 14 Sep 2021 12:29:28 +0300 Subject: [PATCH 2/2] Fix `mqtt_disconnect_impl` to work with no channel --- source/client.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/source/client.c b/source/client.c index bc8057af..cc195ace 100644 --- a/source/client.c +++ b/source/client.c @@ -2978,10 +2978,10 @@ int aws_mqtt_client_connection_ping(struct aws_mqtt_client_connection *connectio struct mqtt_shutdown_task { int error_code; - struct aws_channel_task task; + struct aws_task task; }; -static void s_mqtt_disconnect_task(struct aws_channel_task *channel_task, void *arg, enum aws_task_status status) { +static void s_mqtt_disconnect_task(struct aws_task *channel_task, void *arg, enum aws_task_status status) { (void)status; @@ -3005,17 +3005,20 @@ static void s_mqtt_disconnect_task(struct aws_channel_task *channel_task, void * if (connection->slot && connection->slot->channel) { aws_channel_shutdown(connection->slot->channel, task->error_code); + } else { + // Channel didn't exist, shut down the connection + s_mqtt_client_shutdown(connection->client->bootstrap, task->error_code, NULL, connection); } aws_mem_release(connection->allocator, task); } void mqtt_disconnect_impl(struct aws_mqtt_client_connection *connection, int error_code) { - if (connection->slot) { - struct mqtt_shutdown_task *shutdown_task = - aws_mem_calloc(connection->allocator, 1, sizeof(struct mqtt_shutdown_task)); - shutdown_task->error_code = error_code; - aws_channel_task_init(&shutdown_task->task, s_mqtt_disconnect_task, connection, "mqtt_disconnect"); - aws_channel_schedule_task_now(connection->slot->channel, &shutdown_task->task); - } + struct mqtt_shutdown_task *shutdown_task = + aws_mem_calloc(connection->allocator, 1, sizeof(struct mqtt_shutdown_task)); + shutdown_task->error_code = error_code; + aws_task_init(&shutdown_task->task, s_mqtt_disconnect_task, connection, "mqtt_disconnect"); + struct aws_event_loop *el = + aws_event_loop_group_get_next_loop(connection->client->bootstrap->event_loop_group); + aws_event_loop_schedule_task_now(el, &shutdown_task->task); }