/* everything was written: set back connection state
and back to application task */
/* Re-check current_msg validity before accessing it (err_tcp may have cleared it) */
- if (conn->current_msg != NULL) {
- /* Normal cleanup: current_msg is still valid, so we need to clean up */
- sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
- conn->current_msg->err = err;
- /* Reset state BEFORE clearing current_msg to avoid race condition:
- * If poll_tcp/sent_tcp is called between these two assignments,
- * we want state to be NETCONN_NONE (not NETCONN_WRITE) when current_msg is NULL */
- conn->state = NETCONN_NONE;
- conn->current_msg = NULL;
+ if (conn->current_msg != NULL && conn->state == NETCONN_WRITE) {
+ /* Normal cleanup: current_msg is still valid, so we need to clean up
+ * Double-check to ensure err_tcp hasn't cleared it between check and use */
+ struct api_msg *msg_to_cleanup = conn->current_msg;
+ if (conn->current_msg == msg_to_cleanup && conn->state == NETCONN_WRITE) {
+ sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(msg_to_cleanup);
+ msg_to_cleanup->err = err;
+ /* Reset state BEFORE clearing current_msg to avoid race condition:
+ * If poll_tcp/sent_tcp is called between these two assignments,
+ * we want state to be NETCONN_NONE (not NETCONN_WRITE) when current_msg is NULL */
+ conn->state = NETCONN_NONE;
+ conn->current_msg = NULL;
#if LWIP_TCPIP_CORE_LOCKING
- if (delayed)
+ if (delayed)
#endif
- {
- sys_sem_signal(op_completed_sem);
+ {
+ sys_sem_signal(op_completed_sem);
+ }
+ } else {
+ /* current_msg was changed or state changed by err_tcp between checks, skip cleanup */
}
} else {
/* current_msg was already cleared by err_tcp.