mirror of
https://github.com/espressif/esp-lwip.git
synced 2026-06-05 21:04:45 +00:00
sockets: Add support for socket close from another thread
2.1.3-esp:0a9dad95api_msg: Support sock close from another thread 2.1.3-esp:d058bbbesockets: Fix select-waiter when socket closed abruptly 2.1.3-esp:46227e21Fixesd058bbbeto unref socket for both core-lock configs 2.1.3-esp:882716f7sockets: Fix potential race when socket is closed already 2.1.3-esp:8cf7089capi_msg: Fixes for sock close from another thread 2.1.3-esp:66666948sockets: Fix free-select-locked after udp close
This commit is contained in:
@@ -588,6 +588,9 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
|
||||
tcp_err(pcb, NULL);
|
||||
/* remove reference from to the pcb from this netconn */
|
||||
newconn->pcb.tcp = NULL;
|
||||
#if ESP_LWIP && LWIP_NETCONN_FULLDUPLEX
|
||||
newconn->flags |= NETCONN_FLAG_MBOXINVALID;
|
||||
#endif /* ESP_LWIP && LWIP_NETCONN_FULLDUPLEX */
|
||||
/* no need to drain since we know the recvmbox is empty. */
|
||||
sys_mbox_free(&newconn->recvmbox);
|
||||
sys_mbox_set_invalid(&newconn->recvmbox);
|
||||
@@ -876,6 +879,9 @@ netconn_drain(struct netconn *conn)
|
||||
/* Only tcp pcbs have an acceptmbox, so no need to check conn->type */
|
||||
/* pcb might be set to NULL already by err_tcp() */
|
||||
/* drain recvmbox */
|
||||
#if ESP_LWIP
|
||||
newconn->flags |= NETCONN_FLAG_MBOXINVALID;
|
||||
#endif /* ESP_LWIP */
|
||||
netconn_drain(newconn);
|
||||
if (newconn->pcb.tcp != NULL) {
|
||||
tcp_abort(newconn->pcb.tcp);
|
||||
@@ -1121,6 +1127,9 @@ lwip_netconn_do_delconn(void *m)
|
||||
enum netconn_state state = msg->conn->state;
|
||||
LWIP_ASSERT("netconn state error", /* this only happens for TCP netconns */
|
||||
(state == NETCONN_NONE) || (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP));
|
||||
#if ESP_LWIP
|
||||
msg->err = ERR_OK;
|
||||
#endif
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
/* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */
|
||||
if (state != NETCONN_NONE) {
|
||||
@@ -1133,6 +1142,9 @@ lwip_netconn_do_delconn(void *m)
|
||||
msg->conn->current_msg->err = ERR_CLSD;
|
||||
msg->conn->current_msg = NULL;
|
||||
msg->conn->state = NETCONN_NONE;
|
||||
#if ESP_LWIP
|
||||
msg->err = ERR_INPROGRESS;
|
||||
#endif
|
||||
sys_sem_signal(op_completed_sem);
|
||||
}
|
||||
}
|
||||
@@ -1147,9 +1159,11 @@ lwip_netconn_do_delconn(void *m)
|
||||
} else
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
{
|
||||
#if !ESP_LWIP
|
||||
LWIP_ASSERT("blocking connect in progress",
|
||||
(state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
|
||||
msg->err = ERR_OK;
|
||||
#endif /* ESP_LWIP */
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
/* Mark mboxes invalid */
|
||||
netconn_mark_mbox_invalid(msg->conn);
|
||||
|
||||
+29
-1
@@ -482,6 +482,10 @@ tryget_socket_unconn_locked(int fd)
|
||||
{
|
||||
struct lwip_sock *ret = tryget_socket_unconn_nouse(fd);
|
||||
if (ret != NULL) {
|
||||
#if ESP_LWIP
|
||||
if (ret->conn == NULL)
|
||||
return NULL;
|
||||
#endif /* ESP_LWIP */
|
||||
if (!sock_inc_used_locked(ret)) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -600,6 +604,9 @@ free_socket_locked(struct lwip_sock *sock, int is_tcp, struct netconn **conn,
|
||||
|
||||
*lastdata = sock->lastdata;
|
||||
sock->lastdata.pbuf = NULL;
|
||||
#if ESP_LWIP
|
||||
sock->select_waiting = 0;
|
||||
#endif /* ESP_LWIP */
|
||||
*conn = sock->conn;
|
||||
sock->conn = NULL;
|
||||
return 1;
|
||||
@@ -2621,6 +2628,9 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
||||
static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent)
|
||||
{
|
||||
struct lwip_select_cb *scb;
|
||||
#if ESP_LWIP
|
||||
struct lwip_sock *sock;
|
||||
#endif /* ESP_LWIP */
|
||||
#if !LWIP_TCPIP_CORE_LOCKING
|
||||
int last_select_cb_ctr;
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
@@ -2628,6 +2638,9 @@ static void select_check_waiters(int s, int has_recvevent, int has_sendevent, in
|
||||
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
|
||||
#if ESP_LWIP
|
||||
sock = tryget_socket_unconn(s);
|
||||
#endif /* ESP_LWIP */
|
||||
#if !LWIP_TCPIP_CORE_LOCKING
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
again:
|
||||
@@ -2649,17 +2662,29 @@ again:
|
||||
#if LWIP_SOCKET_SELECT
|
||||
{
|
||||
/* Test this select call for our socket */
|
||||
#if ESP_LWIP
|
||||
if (sock->rcvevent) {
|
||||
#else
|
||||
if (has_recvevent) {
|
||||
#endif /* ESP_LWIP */
|
||||
if (scb->readset && FD_ISSET(s, scb->readset)) {
|
||||
do_signal = 1;
|
||||
}
|
||||
}
|
||||
#if ESP_LWIP
|
||||
if (sock->sendevent) {
|
||||
#else
|
||||
if (has_sendevent) {
|
||||
#endif /* ESP_LWIP */
|
||||
if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) {
|
||||
do_signal = 1;
|
||||
}
|
||||
}
|
||||
#if ESP_LWIP
|
||||
if (sock->errevent) {
|
||||
#else
|
||||
if (has_errevent) {
|
||||
#endif /* ESP_LWIP */
|
||||
if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) {
|
||||
do_signal = 1;
|
||||
}
|
||||
@@ -2689,7 +2714,10 @@ again:
|
||||
last_select_cb_ctr = select_cb_ctr;
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
#endif
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
#if ESP_LWIP
|
||||
done_socket(sock);
|
||||
#endif /* ESP_LWIP */
|
||||
}
|
||||
#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
|
||||
|
||||
|
||||
@@ -91,4 +91,7 @@
|
||||
/* Check lwip_stats.mem.illegal instead of asserting */
|
||||
#define LWIP_MEM_ILLEGAL_FREE(msg) /* to nothing */
|
||||
|
||||
/* Enable Espressif specific options */
|
||||
#define ESP_LWIP 1
|
||||
|
||||
#endif /* LWIP_HDR_LWIPOPTS_H */
|
||||
|
||||
Reference in New Issue
Block a user