-
Notifications
You must be signed in to change notification settings - Fork 39
Error/closing stability #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -253,7 +253,7 @@ static inline lwip_tcp_event_packet_t *_get_async_event() { | |||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| static void _remove_events_for_client(AsyncClient *client) { | ||||||||||
| static size_t _remove_events_for_client(AsyncClient *client) { | ||||||||||
| lwip_tcp_event_packet_t *removed_event_chain; | ||||||||||
| { | ||||||||||
| queue_mutex_guard guard; | ||||||||||
|
|
@@ -269,6 +269,7 @@ static void _remove_events_for_client(AsyncClient *client) { | |||||||||
| removed_event_chain = t->next; | ||||||||||
| _free_event(t); | ||||||||||
| } | ||||||||||
| return count; | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| void AsyncTCP_detail::handle_async_event(lwip_tcp_event_packet_t *e) { | ||||||||||
|
|
@@ -484,7 +485,8 @@ void AsyncTCP_detail::tcp_error(void *arg, int8_t err) { | |||||||||
| // ets_printf("+E: 0x%08x\n", arg); | ||||||||||
| AsyncClient *client = reinterpret_cast<AsyncClient *>(arg); | ||||||||||
| if (client && client->_pcb) { | ||||||||||
| _reset_tcp_callbacks(client->_pcb, client); | ||||||||||
| // The pcb has already been freed by LwIP; do not attempt to clear the callbacks! | ||||||||||
| _remove_events_for_client(client); | ||||||||||
| client->_pcb = nullptr; | ||||||||||
| } | ||||||||||
|
|
||||||||||
|
|
@@ -615,26 +617,35 @@ static esp_err_t _tcp_recved(tcp_pcb **pcb, size_t len) { | |||||||||
| } | ||||||||||
|
|
||||||||||
| static err_t _tcp_close_api(struct tcpip_api_call_data *api_call_msg) { | ||||||||||
| // Unlike the other calls, this is not a direct wrapper of the LwIP function; | ||||||||||
| // we perform the AsyncClient teardown interlocked safely with the LwIP task. | ||||||||||
|
|
||||||||||
| // As a postcondition, the queue must not have any events referencing | ||||||||||
| // the AsyncClient in api_call_msg->close. This is because it is possible for | ||||||||||
| // an error event to have been queued, clearing the pcb*, but after the async | ||||||||||
| // thread has committed to closing/destructing the AsyncClient object. | ||||||||||
|
|
||||||||||
| tcp_api_call_t *msg = (tcp_api_call_t *)api_call_msg; | ||||||||||
| msg->err = ERR_CONN; | ||||||||||
| if (*msg->pcb) { | ||||||||||
| // Unlike the other calls, this is not a direct wrapper of the LwIP function; | ||||||||||
| // we perform the AsyncClient teardown interlocked safely with the LwIP task. | ||||||||||
| tcp_pcb *pcb = *msg->pcb; | ||||||||||
| _reset_tcp_callbacks(pcb, msg->close); | ||||||||||
| msg->err = tcp_close(pcb); | ||||||||||
| if (msg->err != ERR_OK) { | ||||||||||
| if (tcp_close(pcb) != ERR_OK) { | ||||||||||
| // We do not permit failure here: abandon the pcb anyways. | ||||||||||
| tcp_abort(pcb); | ||||||||||
| } | ||||||||||
| msg->err = ERR_OK; | ||||||||||
| *msg->pcb = nullptr; // PCB is now the property of LwIP | ||||||||||
| } else { | ||||||||||
| // Ensure there is not an error event queued for this client | ||||||||||
| if (_remove_events_for_client(msg->close)) { | ||||||||||
|
||||||||||
| if (_remove_events_for_client(msg->close)) { | |
| if (_remove_events_for_client(msg->close) > 0) { |
Copilot
AI
Jul 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The return value of _remove_events_for_client is ignored here, unlike in the close API where it's used to determine if dispose should be run. Consider documenting why the return value is not needed in the abort case or handle it consistently.
| _remove_events_for_client(msg->close); | |
| if (_remove_events_for_client(msg->close)) { | |
| msg->err = ERR_OK; // dispose needs to be run | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable 'count' is being returned but is never declared or initialized in the function. This will cause a compilation error.