net/tcp: replace net_lock with conn_lock and conn_lock_dev

Protect tcp resources through netdev_lock, conn_lock, and tcp_list_lock

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu
2025-07-16 20:56:46 +08:00
committed by Xiang Xiao
parent 6196550f8f
commit 5032377c34
20 changed files with 182 additions and 110 deletions
+2 -6
View File
@@ -68,8 +68,6 @@ static ssize_t netprocfs_tcpstats(FAR struct netprocfs_file_s *priv,
FAR void *laddr; FAR void *laddr;
FAR void *raddr; FAR void *raddr;
net_lock();
while ((conn = tcp_nextconn(conn)) != NULL) while ((conn = tcp_nextconn(conn)) != NULL)
{ {
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) #if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
@@ -125,8 +123,6 @@ static ssize_t netprocfs_tcpstats(FAR struct netprocfs_file_s *priv,
ntohs(conn->rport)); ntohs(conn->rport));
} }
net_unlock();
return len; return len;
} }
@@ -158,7 +154,7 @@ ssize_t netprocfs_read_tcpstats(FAR struct netprocfs_file_s *priv,
int skip = 1; int skip = 1;
int len = 0; int len = 0;
net_lock(); tcp_conn_list_lock();
if (tcp_nextconn(NULL) != NULL) if (tcp_nextconn(NULL) != NULL)
{ {
@@ -192,7 +188,7 @@ ssize_t netprocfs_read_tcpstats(FAR struct netprocfs_file_s *priv,
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
} }
net_unlock(); tcp_conn_list_unlock();
return len; return len;
} }
+20
View File
@@ -696,6 +696,26 @@ int tcp_connect(FAR struct tcp_conn_s *conn,
void tcp_removeconn(FAR struct tcp_conn_s *conn); void tcp_removeconn(FAR struct tcp_conn_s *conn);
/****************************************************************************
* Name: tcp_conn_list_lock
*
* Description:
* Lock the TCP connection list.
*
****************************************************************************/
void tcp_conn_list_lock(void);
/****************************************************************************
* Name: tcp_conn_list_unlock
*
* Description:
* Unlock the TCP connection list.
*
****************************************************************************/
void tcp_conn_list_unlock(void);
/**************************************************************************** /****************************************************************************
* Name: psock_tcp_connect * Name: psock_tcp_connect
* *
+14 -5
View File
@@ -39,6 +39,7 @@
#include <nuttx/net/net.h> #include <nuttx/net/net.h>
#include "socket/socket.h" #include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
/**************************************************************************** /****************************************************************************
@@ -217,7 +218,7 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
{ {
FAR struct tcp_conn_s *conn; FAR struct tcp_conn_s *conn;
struct accept_s state; struct accept_s state;
int ret; int ret = OK;
/* Check the backlog to see if there is a connection already pending for /* Check the backlog to see if there is a connection already pending for
* this listener. * this listener.
@@ -225,6 +226,8 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
conn = psock->s_conn; conn = psock->s_conn;
conn_lock(&conn->sconn);
#ifdef CONFIG_NET_TCPBACKLOG #ifdef CONFIG_NET_TCPBACKLOG
state.acpt_newconn = tcp_backlogremove(conn); state.acpt_newconn = tcp_backlogremove(conn);
if (state.acpt_newconn) if (state.acpt_newconn)
@@ -243,7 +246,8 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
else if (_SS_ISNONBLOCK(conn->sconn.s_flags)) else if (_SS_ISNONBLOCK(conn->sconn.s_flags))
{ {
return -EAGAIN; ret = -EAGAIN;
goto out;
} }
else else
#endif #endif
@@ -271,7 +275,9 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
* net_sem_wait will also terminate if a signal is received. * net_sem_wait will also terminate if a signal is received.
*/ */
conn_unlock(&conn->sconn);
ret = net_sem_wait(&state.acpt_sem); ret = net_sem_wait(&state.acpt_sem);
conn_lock(&conn->sconn);
/* Make sure that no further events are processed */ /* Make sure that no further events are processed */
@@ -287,7 +293,7 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
if (state.acpt_result != 0) if (state.acpt_result != 0)
{ {
DEBUGASSERT(state.acpt_result > 0); DEBUGASSERT(state.acpt_result > 0);
return -state.acpt_result; ret = -state.acpt_result;
} }
/* If net_sem_wait failed, then we were probably reawakened by a /* If net_sem_wait failed, then we were probably reawakened by a
@@ -297,12 +303,15 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
if (ret < 0) if (ret < 0)
{ {
return ret; goto out;
} }
} }
*newconn = (FAR void *)state.acpt_newconn; *newconn = (FAR void *)state.acpt_newconn;
return OK;
out:
conn_unlock(&conn->sconn);
return ret;
} }
#endif /* CONFIG_NET_TCP */ #endif /* CONFIG_NET_TCP */
+3 -2
View File
@@ -37,6 +37,7 @@
#include <nuttx/net/net.h> #include <nuttx/net/net.h>
#include "devif/devif.h" #include "devif/devif.h"
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
/**************************************************************************** /****************************************************************************
@@ -118,7 +119,7 @@ int tcp_backlogcreate(FAR struct tcp_conn_s *conn, int nblg)
/* Destroy any existing backlog (shouldn't be any) */ /* Destroy any existing backlog (shouldn't be any) */
net_lock(); conn_lock(&conn->sconn);
tcp_backlogdestroy(conn); tcp_backlogdestroy(conn);
/* Now install the backlog tear-off in the connection. NOTE that bls may /* Now install the backlog tear-off in the connection. NOTE that bls may
@@ -128,7 +129,7 @@ int tcp_backlogcreate(FAR struct tcp_conn_s *conn, int nblg)
*/ */
conn->backlog = bls; conn->backlog = bls;
net_unlock(); conn_unlock(&conn->sconn);
return OK; return OK;
} }
+3 -2
View File
@@ -436,11 +436,12 @@ uint16_t tcp_datahandler(FAR struct net_driver_s *dev,
void tcp_callback_cleanup(FAR void *arg) void tcp_callback_cleanup(FAR void *arg)
{ {
FAR struct tcp_callback_s *cb = (FAR struct tcp_callback_s *)arg; FAR struct tcp_callback_s *cb = (FAR struct tcp_callback_s *)arg;
FAR struct tcp_conn_s *conn = cb->tc_conn;
net_lock(); conn_dev_lock(&conn->sconn, conn->dev);
nerr("ERROR: pthread is being canceled, need to cleanup cb\n"); nerr("ERROR: pthread is being canceled, need to cleanup cb\n");
tcp_callback_free(cb->tc_conn, *(cb->tc_cb)); tcp_callback_free(cb->tc_conn, *(cb->tc_cb));
nxsem_destroy(cb->tc_sem); nxsem_destroy(cb->tc_sem);
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
} }
#endif /* NET_TCP_HAVE_STACK */ #endif /* NET_TCP_HAVE_STACK */
+7 -7
View File
@@ -40,6 +40,7 @@
#include "devif/devif.h" #include "devif/devif.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
#include "socket/socket.h" #include "socket/socket.h"
#include "utils/utils.h"
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
@@ -53,18 +54,16 @@ static void tcp_close_work(FAR void *param)
{ {
FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)param; FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)param;
net_lock();
conn->flags &= ~TCP_CLOSE_ARRANGED; conn->flags &= ~TCP_CLOSE_ARRANGED;
if (conn->crefs == 0) if (conn->crefs == 0)
{ {
/* Stop the network monitor for all sockets */ /* Stop the network monitor for all sockets */
conn_dev_lock(&conn->sconn, conn->dev);
tcp_stop_monitor(conn, TCP_CLOSE); tcp_stop_monitor(conn, TCP_CLOSE);
conn_dev_unlock(&conn->sconn, conn->dev);
tcp_free(conn); tcp_free(conn);
} }
net_unlock();
} }
/**************************************************************************** /****************************************************************************
@@ -220,10 +219,10 @@ static inline int tcp_close_disconnect(FAR struct socket *psock)
/* Interrupts are disabled here to avoid race conditions */ /* Interrupts are disabled here to avoid race conditions */
net_lock();
conn = psock->s_conn; conn = psock->s_conn;
conn_dev_lock(&conn->sconn, conn->dev);
/* Discard our reference to the connection */ /* Discard our reference to the connection */
conn->crefs = 0; conn->crefs = 0;
@@ -279,12 +278,14 @@ static inline int tcp_close_disconnect(FAR struct socket *psock)
/* Notify the device driver of the availability of TX data */ /* Notify the device driver of the availability of TX data */
tcp_send_txnotify(psock, conn); tcp_send_txnotify(psock, conn);
conn_dev_unlock(&conn->sconn, conn->dev);
} }
else else
{ {
/* Stop the network monitor for all sockets */ /* Stop the network monitor for all sockets */
tcp_stop_monitor(conn, TCP_CLOSE); tcp_stop_monitor(conn, TCP_CLOSE);
conn_dev_unlock(&conn->sconn, conn->dev);
/* Free network resources */ /* Free network resources */
@@ -293,7 +294,6 @@ static inline int tcp_close_disconnect(FAR struct socket *psock)
psock->s_conn = NULL; psock->s_conn = NULL;
net_unlock();
return ret; return ret;
} }
+55 -40
View File
@@ -343,11 +343,8 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
/* Verify or select a local port and address */ /* Verify or select a local port and address */
net_lock();
if (conn->lport != 0) if (conn->lport != 0)
{ {
net_unlock();
return -EINVAL; return -EINVAL;
} }
@@ -372,7 +369,6 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
if (ret == -EADDRNOTAVAIL) if (ret == -EADDRNOTAVAIL)
{ {
net_unlock();
return ret; return ret;
} }
} }
@@ -385,7 +381,6 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
if (port < 0) if (port < 0)
{ {
nerr("ERROR: tcp_selectport failed: %d\n", port); nerr("ERROR: tcp_selectport failed: %d\n", port);
net_unlock();
return port; return port;
} }
@@ -411,7 +406,6 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
net_ipv4addr_copy(conn->u.ipv4.laddr, INADDR_ANY); net_ipv4addr_copy(conn->u.ipv4.laddr, INADDR_ANY);
} }
net_unlock();
return ret; return ret;
} }
#endif /* CONFIG_NET_IPv4 */ #endif /* CONFIG_NET_IPv4 */
@@ -441,11 +435,8 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
/* Verify or select a local port and address */ /* Verify or select a local port and address */
net_lock();
if (conn->lport != 0) if (conn->lport != 0)
{ {
net_unlock();
return -EINVAL; return -EINVAL;
} }
@@ -472,7 +463,6 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
netdev_list_unlock(); netdev_list_unlock();
if (ret == -EADDRNOTAVAIL) if (ret == -EADDRNOTAVAIL)
{ {
net_unlock();
return ret; return ret;
} }
} }
@@ -487,7 +477,6 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
if (port < 0) if (port < 0)
{ {
nerr("ERROR: tcp_selectport failed: %d\n", port); nerr("ERROR: tcp_selectport failed: %d\n", port);
net_unlock();
return port; return port;
} }
@@ -513,7 +502,6 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
net_ipv6addr_copy(conn->u.ipv6.laddr, g_ipv6_unspecaddr); net_ipv6addr_copy(conn->u.ipv6.laddr, g_ipv6_unspecaddr);
} }
net_unlock();
return ret; return ret;
} }
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
@@ -561,6 +549,7 @@ int tcp_selectport(uint8_t domain,
NET_PORT_RANDOM_INIT(g_last_tcp_port); NET_PORT_RANDOM_INIT(g_last_tcp_port);
} }
tcp_conn_list_lock();
if (portno == 0) if (portno == 0)
{ {
uint16_t loop_start = g_last_tcp_port; uint16_t loop_start = g_last_tcp_port;
@@ -609,6 +598,7 @@ int tcp_selectport(uint8_t domain,
/* Return the selected or verified port number (host byte order) */ /* Return the selected or verified port number (host byte order) */
tcp_conn_list_unlock();
return portno; return portno;
} }
@@ -632,7 +622,7 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain)
* locked in any cased while accessing g_free_tcp_connections[]; * locked in any cased while accessing g_free_tcp_connections[];
*/ */
net_lock(); tcp_conn_list_lock();
/* Return the entry from the head of the free list */ /* Return the entry from the head of the free list */
@@ -714,7 +704,7 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain)
} }
#endif #endif
net_unlock(); tcp_conn_list_unlock();
/* Mark the connection allocated */ /* Mark the connection allocated */
@@ -739,6 +729,7 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain)
nxsem_init(&conn->snd_sem, 0, 0); nxsem_init(&conn->snd_sem, 0, 0);
#endif #endif
nxmutex_init(&conn->sconn.s_lock);
/* Set the default value of mss to max, this field will changed when /* Set the default value of mss to max, this field will changed when
* receive SYN. * receive SYN.
@@ -815,13 +806,6 @@ void tcp_free(FAR struct tcp_conn_s *conn)
FAR struct tcp_wrbuffer_s *wrbuffer; FAR struct tcp_wrbuffer_s *wrbuffer;
#endif #endif
/* Because g_free_tcp_connections is accessed from user level and event
* processing logic, it is necessary to keep the network locked during this
* operation.
*/
net_lock();
DEBUGASSERT(conn->crefs == 0); DEBUGASSERT(conn->crefs == 0);
/* Cancel close work */ /* Cancel close work */
@@ -831,7 +815,6 @@ void tcp_free(FAR struct tcp_conn_s *conn)
{ {
/* Close work is already running, tcp_free will be called again. */ /* Close work is already running, tcp_free will be called again. */
net_unlock();
return; return;
} }
@@ -841,6 +824,7 @@ void tcp_free(FAR struct tcp_conn_s *conn)
/* Make sure monitor is stopped. */ /* Make sure monitor is stopped. */
conn_dev_lock(&conn->sconn, conn->dev);
tcp_stop_monitor(conn, TCP_CLOSE); tcp_stop_monitor(conn, TCP_CLOSE);
/* Free remaining callbacks, actually there should be only the send /* Free remaining callbacks, actually there should be only the send
@@ -853,6 +837,8 @@ void tcp_free(FAR struct tcp_conn_s *conn)
tcp_callback_free(conn, cb); tcp_callback_free(conn, cb);
} }
conn_dev_unlock(&conn->sconn, conn->dev);
/* TCP_ALLOCATED means that that the connection is not in the active list /* TCP_ALLOCATED means that that the connection is not in the active list
* yet. * yet.
*/ */
@@ -861,9 +847,12 @@ void tcp_free(FAR struct tcp_conn_s *conn)
{ {
/* Remove the connection from the active list */ /* Remove the connection from the active list */
tcp_conn_list_lock();
dq_rem(&conn->sconn.node, &g_active_tcp_connections); dq_rem(&conn->sconn.node, &g_active_tcp_connections);
tcp_conn_list_unlock();
} }
nxmutex_destroy(&conn->sconn.s_lock);
tcp_free_rx_buffers(conn); tcp_free_rx_buffers(conn);
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS #ifdef CONFIG_NET_TCP_WRITE_BUFFERS
@@ -918,8 +907,6 @@ void tcp_free(FAR struct tcp_conn_s *conn)
/* Free the connection structure */ /* Free the connection structure */
NET_BUFPOOL_FREE(g_tcp_connections, conn); NET_BUFPOOL_FREE(g_tcp_connections, conn);
net_unlock();
} }
/**************************************************************************** /****************************************************************************
@@ -937,12 +924,15 @@ void tcp_free(FAR struct tcp_conn_s *conn)
FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev,
FAR struct tcp_hdr_s *tcp) FAR struct tcp_hdr_s *tcp)
{ {
FAR struct tcp_conn_s *conn = NULL;
tcp_conn_list_lock();
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv4
if (IFF_IS_IPv6(dev->d_flags)) if (IFF_IS_IPv6(dev->d_flags))
#endif #endif
{ {
return tcp_ipv6_active(dev, tcp); conn = tcp_ipv6_active(dev, tcp);
} }
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
@@ -951,9 +941,12 @@ FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev,
else else
#endif #endif
{ {
return tcp_ipv4_active(dev, tcp); conn = tcp_ipv4_active(dev, tcp);
} }
#endif /* CONFIG_NET_IPv4 */ #endif /* CONFIG_NET_IPv4 */
tcp_conn_list_unlock();
return conn;
} }
/**************************************************************************** /****************************************************************************
@@ -1162,7 +1155,10 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
* Interrupts should already be disabled in this context. * Interrupts should already be disabled in this context.
*/ */
tcp_conn_list_lock();
dq_addlast(&conn->sconn.node, &g_active_tcp_connections); dq_addlast(&conn->sconn.node, &g_active_tcp_connections);
tcp_conn_list_unlock();
tcp_update_retrantimer(conn, TCP_RTO); tcp_update_retrantimer(conn, TCP_RTO);
} }
@@ -1243,7 +1239,7 @@ int tcp_bind(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr) int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
{ {
int port; int port;
int ret = OK; int ret;
/* The connection is expected to be in the TCP_ALLOCATED state.. i.e., /* The connection is expected to be in the TCP_ALLOCATED state.. i.e.,
* allocated via up_tcpalloc(), but not yet put into the active connections * allocated via up_tcpalloc(), but not yet put into the active connections
@@ -1260,8 +1256,6 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
* but the port may still be INPORT_ANY. * but the port may still be INPORT_ANY.
*/ */
net_lock();
/* Check if the local port has been bind() */ /* Check if the local port has been bind() */
port = conn->lport; port = conn->lport;
@@ -1302,8 +1296,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
if (port < 0) if (port < 0)
{ {
ret = port; return port;
goto errout_with_lock;
} }
} }
@@ -1387,7 +1380,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
*/ */
nerr("ERROR: Failed to find network device: %d\n", ret); nerr("ERROR: Failed to find network device: %d\n", ret);
goto errout_with_lock; return ret;
} }
#if defined(CONFIG_NET_ARP_SEND) || defined(CONFIG_NET_ICMPv6_NEIGHBOR) #if defined(CONFIG_NET_ARP_SEND) || defined(CONFIG_NET_ICMPv6_NEIGHBOR)
@@ -1417,8 +1410,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
if (ret < 0) if (ret < 0)
{ {
ret = -ENETUNREACH; return -ENETUNREACH;
goto errout_with_lock;
} }
#endif /* CONFIG_NET_ARP_SEND || CONFIG_NET_ICMPv6_NEIGHBOR */ #endif /* CONFIG_NET_ARP_SEND || CONFIG_NET_ICMPv6_NEIGHBOR */
@@ -1473,12 +1465,37 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
/* And, finally, put the connection structure into the active list. */ /* And, finally, put the connection structure into the active list. */
tcp_conn_list_lock();
dq_addlast(&conn->sconn.node, &g_active_tcp_connections); dq_addlast(&conn->sconn.node, &g_active_tcp_connections);
ret = OK; tcp_conn_list_unlock();
errout_with_lock: return OK;
net_unlock(); }
return ret;
/****************************************************************************
* Name: tcp_conn_list_lock
*
* Description:
* Lock the TCP connection list.
*
****************************************************************************/
void tcp_conn_list_lock(void)
{
NET_BUFPOOL_LOCK(g_tcp_connections);
}
/****************************************************************************
* Name: tcp_conn_list_unlock
*
* Description:
* Unlock the TCP connection list.
*
****************************************************************************/
void tcp_conn_list_unlock(void)
{
NET_BUFPOOL_UNLOCK(g_tcp_connections);
} }
/**************************************************************************** /****************************************************************************
@@ -1494,9 +1511,7 @@ errout_with_lock:
void tcp_removeconn(FAR struct tcp_conn_s *conn) void tcp_removeconn(FAR struct tcp_conn_s *conn)
{ {
net_lock();
dq_rem(&conn->sconn.node, &g_active_tcp_connections); dq_rem(&conn->sconn.node, &g_active_tcp_connections);
net_unlock();
} }
#endif /* CONFIG_NET && CONFIG_NET_TCP */ #endif /* CONFIG_NET && CONFIG_NET_TCP */
+6 -3
View File
@@ -47,6 +47,7 @@
#include "netdev/netdev.h" #include "netdev/netdev.h"
#include "socket/socket.h" #include "socket/socket.h"
#include "inet/inet.h" #include "inet/inet.h"
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
#ifdef NET_TCP_HAVE_STACK #ifdef NET_TCP_HAVE_STACK
@@ -304,8 +305,6 @@ int psock_tcp_connect(FAR struct socket *psock,
* setup. * setup.
*/ */
net_lock();
conn = psock->s_conn; conn = psock->s_conn;
/* Get the connection reference from the socket */ /* Get the connection reference from the socket */
@@ -367,6 +366,7 @@ int psock_tcp_connect(FAR struct socket *psock,
{ {
/* Set up the callbacks in the connection */ /* Set up the callbacks in the connection */
conn_dev_lock(&conn->sconn, conn->dev);
ret = psock_setup_callbacks(psock, &state); ret = psock_setup_callbacks(psock, &state);
if (ret >= 0) if (ret >= 0)
{ {
@@ -377,6 +377,7 @@ int psock_tcp_connect(FAR struct socket *psock,
info.tc_conn = conn; info.tc_conn = conn;
info.tc_cb = &state.tc_cb; info.tc_cb = &state.tc_cb;
info.tc_sem = &state.tc_sem; info.tc_sem = &state.tc_sem;
conn_dev_unlock(&conn->sconn, conn->dev);
tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info); tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info);
/* Notify the device driver that new connection is available. */ /* Notify the device driver that new connection is available. */
@@ -392,6 +393,7 @@ int psock_tcp_connect(FAR struct socket *psock,
ret = net_sem_wait(&state.tc_sem); ret = net_sem_wait(&state.tc_sem);
tls_cleanup_pop(tls_get_info(), 0); tls_cleanup_pop(tls_get_info(), 0);
conn_dev_lock(&conn->sconn, conn->dev);
/* Uninitialize the state structure */ /* Uninitialize the state structure */
@@ -412,6 +414,8 @@ int psock_tcp_connect(FAR struct socket *psock,
psock_teardown_callbacks(&state, ret); psock_teardown_callbacks(&state, ret);
} }
conn_dev_unlock(&conn->sconn, conn->dev);
} }
/* Check if the socket was successfully connected. */ /* Check if the socket was successfully connected. */
@@ -443,7 +447,6 @@ int psock_tcp_connect(FAR struct socket *psock,
} }
} }
net_unlock();
return ret; return ret;
} }
+3
View File
@@ -55,6 +55,7 @@
#include <nuttx/net/tcp.h> #include <nuttx/net/tcp.h>
#include "devif/devif.h" #include "devif/devif.h"
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
/**************************************************************************** /****************************************************************************
@@ -117,6 +118,7 @@ void tcp_poll(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
* setup may not actually be used. * setup may not actually be used.
*/ */
conn_lock(&conn->sconn);
tcp_ip_select(conn); tcp_ip_select(conn);
/* Perform the callback */ /* Perform the callback */
@@ -126,6 +128,7 @@ void tcp_poll(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
/* Handle the callback response */ /* Handle the callback response */
tcp_appsend(dev, conn, result); tcp_appsend(dev, conn, result);
conn_unlock(&conn->sconn);
} }
} }
+3 -2
View File
@@ -38,6 +38,7 @@
#include <nuttx/mm/iob.h> #include <nuttx/mm/iob.h>
#include <nuttx/net/net.h> #include <nuttx/net/net.h>
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
/**************************************************************************** /****************************************************************************
@@ -121,7 +122,7 @@ int tcp_ioctl(FAR struct tcp_conn_s *conn, int cmd, unsigned long arg)
{ {
int ret = OK; int ret = OK;
net_lock(); conn_lock(&conn->sconn);
switch (cmd) switch (cmd)
{ {
@@ -156,7 +157,7 @@ int tcp_ioctl(FAR struct tcp_conn_s *conn, int cmd, unsigned long arg)
break; break;
} }
net_unlock(); conn_unlock(&conn->sconn);
return ret; return ret;
} }
+8 -4
View File
@@ -93,6 +93,7 @@ FAR struct tcp_conn_s *tcp_findlistener(FAR union ip_binding_u *uaddr,
/* Examine each connection structure in each slot of the listener list */ /* Examine each connection structure in each slot of the listener list */
tcp_conn_list_lock();
for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++) for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++)
{ {
/* Is this slot assigned? If so, does the connection have the same /* Is this slot assigned? If so, does the connection have the same
@@ -117,6 +118,7 @@ FAR struct tcp_conn_s *tcp_findlistener(FAR union ip_binding_u *uaddr,
{ {
/* Yes.. we found a listener on this port */ /* Yes.. we found a listener on this port */
tcp_conn_list_unlock();
return conn; return conn;
} }
} }
@@ -133,6 +135,7 @@ FAR struct tcp_conn_s *tcp_findlistener(FAR union ip_binding_u *uaddr,
{ {
/* Yes.. we found a listener on this port */ /* Yes.. we found a listener on this port */
tcp_conn_list_unlock();
return conn; return conn;
} }
} }
@@ -142,6 +145,7 @@ FAR struct tcp_conn_s *tcp_findlistener(FAR union ip_binding_u *uaddr,
/* No listener for this port */ /* No listener for this port */
tcp_conn_list_unlock();
return NULL; return NULL;
} }
@@ -165,7 +169,7 @@ int tcp_unlisten(FAR struct tcp_conn_s *conn)
int ndx; int ndx;
int ret = -EINVAL; int ret = -EINVAL;
net_lock(); tcp_conn_list_lock();
for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++) for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++)
{ {
if (tcp_listenports[ndx] == conn) if (tcp_listenports[ndx] == conn)
@@ -176,7 +180,7 @@ int tcp_unlisten(FAR struct tcp_conn_s *conn)
} }
} }
net_unlock(); tcp_conn_list_unlock();
return ret; return ret;
} }
@@ -200,7 +204,7 @@ int tcp_listen(FAR struct tcp_conn_s *conn)
* is accessed from event processing logic as well. * is accessed from event processing logic as well.
*/ */
net_lock(); tcp_conn_list_lock();
/* First, check if there is already a socket listening on this port */ /* First, check if there is already a socket listening on this port */
@@ -239,7 +243,7 @@ int tcp_listen(FAR struct tcp_conn_s *conn)
} }
} }
net_unlock(); tcp_conn_list_unlock();
return ret; return ret;
} }
+3 -9
View File
@@ -34,6 +34,7 @@
#include "devif/devif.h" #include "devif/devif.h"
#include "socket/socket.h" #include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
#ifdef NET_TCP_HAVE_STACK #ifdef NET_TCP_HAVE_STACK
@@ -203,8 +204,6 @@ static void tcp_shutdown_monitor(FAR struct tcp_conn_s *conn, uint16_t flags)
* are informed of the loss of connection event. * are informed of the loss of connection event.
*/ */
net_lock();
/* Free all allocated connection event callback structures */ /* Free all allocated connection event callback structures */
while (conn->connevents != NULL) while (conn->connevents != NULL)
@@ -213,8 +212,6 @@ static void tcp_shutdown_monitor(FAR struct tcp_conn_s *conn, uint16_t flags)
&conn->connevents, &conn->connevents,
&conn->connevents_tail); &conn->connevents_tail);
} }
net_unlock();
} }
/**************************************************************************** /****************************************************************************
@@ -250,8 +247,6 @@ int tcp_start_monitor(FAR struct socket *psock)
conn = psock->s_conn; conn = psock->s_conn;
net_lock();
/* Non-blocking connection ? */ /* Non-blocking connection ? */
nonblock_conn = (conn->tcpstateflags == TCP_SYN_SENT && nonblock_conn = (conn->tcpstateflags == TCP_SYN_SENT &&
@@ -277,7 +272,6 @@ int tcp_start_monitor(FAR struct socket *psock)
if (conn->tcpstateflags == TCP_CLOSED || if (conn->tcpstateflags == TCP_CLOSED ||
conn->tcpstateflags == TCP_LAST_ACK) conn->tcpstateflags == TCP_LAST_ACK)
{ {
net_unlock();
return OK; return OK;
} }
@@ -285,7 +279,6 @@ int tcp_start_monitor(FAR struct socket *psock)
* because the socket was already disconnected. * because the socket was already disconnected.
*/ */
net_unlock();
return -ENOTCONN; return -ENOTCONN;
} }
@@ -293,6 +286,7 @@ int tcp_start_monitor(FAR struct socket *psock)
* the network goes down. * the network goes down.
*/ */
conn_dev_lock(&conn->sconn, conn->dev);
cb = devif_callback_alloc(conn->dev, cb = devif_callback_alloc(conn->dev,
&conn->connevents, &conn->connevents,
&conn->connevents_tail); &conn->connevents_tail);
@@ -310,7 +304,7 @@ int tcp_start_monitor(FAR struct socket *psock)
} }
} }
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
return OK; return OK;
} }
+8 -9
View File
@@ -39,6 +39,7 @@
#include "netdev/netdev.h" #include "netdev/netdev.h"
#include "socket/socket.h" #include "socket/socket.h"
#include "inet/inet.h" #include "inet/inet.h"
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
/**************************************************************************** /****************************************************************************
@@ -207,18 +208,17 @@ int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
/* Some of the following must be atomic */ /* Some of the following must be atomic */
net_lock();
conn = psock->s_conn; conn = psock->s_conn;
/* Sanity check */ /* Sanity check */
if (!conn || !fds) if (!conn || !fds)
{ {
ret = -EINVAL; return -EINVAL;
goto errout_with_lock;
} }
conn_dev_lock(&conn->sconn, conn->dev);
/* Non-blocking connection ? */ /* Non-blocking connection ? */
nonblock_conn = ((conn->tcpstateflags == TCP_ALLOCATED || nonblock_conn = ((conn->tcpstateflags == TCP_ALLOCATED ||
@@ -388,7 +388,7 @@ notify:
poll_notify(&fds, 1, eventset); poll_notify(&fds, 1, eventset);
errout_with_lock: errout_with_lock:
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
return ret; return ret;
} }
@@ -415,18 +415,17 @@ int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds)
/* Some of the following must be atomic */ /* Some of the following must be atomic */
net_lock();
conn = psock->s_conn; conn = psock->s_conn;
/* Sanity check */ /* Sanity check */
if (!conn || !fds->priv) if (!conn || !fds->priv)
{ {
net_unlock();
return -EINVAL; return -EINVAL;
} }
conn_dev_lock(&conn->sconn, conn->dev);
/* Recover the socket descriptor poll state info from the poll structure */ /* Recover the socket descriptor poll state info from the poll structure */
info = (FAR struct tcp_poll_s *)fds->priv; info = (FAR struct tcp_poll_s *)fds->priv;
@@ -446,7 +445,7 @@ int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds)
info->conn = NULL; info->conn = NULL;
} }
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
return OK; return OK;
} }
+8 -4
View File
@@ -42,8 +42,9 @@
#include "netdev/netdev.h" #include "netdev/netdev.h"
#include "devif/devif.h" #include "devif/devif.h"
#include "tcp/tcp.h"
#include "socket/socket.h" #include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h"
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
@@ -805,6 +806,7 @@ static ssize_t tcp_recvfrom_one(FAR struct tcp_conn_s *conn, FAR void *buf,
info.tc_conn = conn; info.tc_conn = conn;
info.tc_cb = &state.ir_cb; info.tc_cb = &state.ir_cb;
info.tc_sem = &state.ir_sem; info.tc_sem = &state.ir_sem;
conn_dev_unlock(&conn->sconn, conn->dev);
tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info); tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info);
/* Wait for either the receive to complete or for an /* Wait for either the receive to complete or for an
@@ -815,6 +817,7 @@ static ssize_t tcp_recvfrom_one(FAR struct tcp_conn_s *conn, FAR void *buf,
ret = net_sem_timedwait(&state.ir_sem, ret = net_sem_timedwait(&state.ir_sem,
_SO_TIMEOUT(conn->sconn.s_rcvtimeo)); _SO_TIMEOUT(conn->sconn.s_rcvtimeo));
tls_cleanup_pop(tls_get_info(), 0); tls_cleanup_pop(tls_get_info(), 0);
conn_dev_lock(&conn->sconn, conn->dev);
if (ret == -ETIMEDOUT) if (ret == -ETIMEDOUT)
{ {
ret = -EAGAIN; ret = -EAGAIN;
@@ -839,7 +842,9 @@ static ssize_t tcp_recvfrom_one(FAR struct tcp_conn_s *conn, FAR void *buf,
if (tcp_should_send_recvwindow(conn)) if (tcp_should_send_recvwindow(conn))
{ {
conn_unlock(&conn->sconn);
netdev_txnotify_dev(conn->dev); netdev_txnotify_dev(conn->dev);
conn_lock(&conn->sconn);
} }
tcp_notify_recvcpu(conn); tcp_notify_recvcpu(conn);
@@ -880,9 +885,8 @@ ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR struct msghdr *msg,
ssize_t ret = 0; ssize_t ret = 0;
int i; int i;
net_lock();
conn = psock->s_conn; conn = psock->s_conn;
conn_dev_lock(&conn->sconn, conn->dev);
for (i = 0; i < msg->msg_iovlen; i++) for (i = 0; i < msg->msg_iovlen; i++)
{ {
FAR void *buf = msg->msg_iov[i].iov_base; FAR void *buf = msg->msg_iov[i].iov_base;
@@ -909,7 +913,7 @@ ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR struct msghdr *msg,
} }
} }
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
return nrecv ? nrecv : ret; return nrecv ? nrecv : ret;
} }
+9 -3
View File
@@ -1409,7 +1409,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
size_t chunk_len = len; size_t chunk_len = len;
ssize_t chunk_result; ssize_t chunk_result;
net_lock(); conn_dev_lock(&conn->sconn, conn->dev);
/* Now that we have the network locked, we need to check the connection /* Now that we have the network locked, we need to check the connection
* state again to ensure the connection is still valid. * state again to ensure the connection is still valid.
@@ -1469,11 +1469,13 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
info.tc_conn = conn; info.tc_conn = conn;
info.tc_cb = &conn->sndcb; info.tc_cb = &conn->sndcb;
info.tc_sem = &conn->snd_sem; info.tc_sem = &conn->snd_sem;
conn_dev_unlock(&conn->sconn, conn->dev);
tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info); tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info);
ret = net_sem_timedwait_uninterruptible(&conn->snd_sem, ret = net_sem_timedwait_uninterruptible(&conn->snd_sem,
tcp_send_gettimeout(start, timeout)); tcp_send_gettimeout(start, timeout));
tls_cleanup_pop(tls_get_info(), 0); tls_cleanup_pop(tls_get_info(), 0);
conn_dev_lock(&conn->sconn, conn->dev);
if (ret < 0) if (ret < 0)
{ {
if (ret == -ETIMEDOUT) if (ret == -ETIMEDOUT)
@@ -1523,8 +1525,10 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
} }
else else
{ {
conn_dev_unlock(&conn->sconn, conn->dev);
wrb = tcp_wrbuffer_timedalloc(tcp_send_gettimeout(start, wrb = tcp_wrbuffer_timedalloc(tcp_send_gettimeout(start,
timeout)); timeout));
conn_dev_lock(&conn->sconn, conn->dev);
ninfo("new wrb %p\n", wrb); ninfo("new wrb %p\n", wrb);
} }
@@ -1630,7 +1634,9 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
* we risk a deadlock with other threads competing on IOBs. * we risk a deadlock with other threads competing on IOBs.
*/ */
conn_dev_unlock(&conn->sconn, conn->dev);
iob = net_iobtimedalloc(true, tcp_send_gettimeout(start, timeout)); iob = net_iobtimedalloc(true, tcp_send_gettimeout(start, timeout));
conn_dev_lock(&conn->sconn, conn->dev);
if (iob != NULL) if (iob != NULL)
{ {
iob_free_chain(iob); iob_free_chain(iob);
@@ -1652,8 +1658,8 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
/* Notify the device driver of the availability of TX data */ /* Notify the device driver of the availability of TX data */
conn_dev_unlock(&conn->sconn, conn->dev);
tcp_send_txnotify(psock, conn); tcp_send_txnotify(psock, conn);
net_unlock();
if (chunk_result == 0) if (chunk_result == 0)
{ {
@@ -1699,7 +1705,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
return result; return result;
errout_with_lock: errout_with_lock:
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
errout: errout:
if (result > 0) if (result > 0)
+6 -3
View File
@@ -55,6 +55,7 @@
#include "icmpv6/icmpv6.h" #include "icmpv6/icmpv6.h"
#include "neighbor/neighbor.h" #include "neighbor/neighbor.h"
#include "route/route.h" #include "route/route.h"
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
/**************************************************************************** /****************************************************************************
@@ -548,7 +549,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
* ready. * ready.
*/ */
net_lock(); conn_dev_lock(&conn->sconn, conn->dev);
/* Now that we have the network locked, we need to check the connection /* Now that we have the network locked, we need to check the connection
* state again to ensure the connection is still valid. * state again to ensure the connection is still valid.
@@ -557,7 +558,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
if (!_SS_ISCONNECTED(conn->sconn.s_flags)) if (!_SS_ISCONNECTED(conn->sconn.s_flags))
{ {
nerr("ERROR: No longer connected\n"); nerr("ERROR: No longer connected\n");
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
ret = -ENOTCONN; ret = -ENOTCONN;
goto errout; goto errout;
} }
@@ -613,11 +614,13 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
info.tc_conn = conn; info.tc_conn = conn;
info.tc_cb = &state.snd_cb; info.tc_cb = &state.snd_cb;
info.tc_sem = &state.snd_sem; info.tc_sem = &state.snd_sem;
conn_dev_unlock(&conn->sconn, conn->dev);
tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info); tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info);
ret = net_sem_timedwait(&state.snd_sem, ret = net_sem_timedwait(&state.snd_sem,
_SO_TIMEOUT(conn->sconn.s_sndtimeo)); _SO_TIMEOUT(conn->sconn.s_sndtimeo));
tls_cleanup_pop(tls_get_info(), 0); tls_cleanup_pop(tls_get_info(), 0);
conn_dev_lock(&conn->sconn, conn->dev);
if (ret != -ETIMEDOUT || acked == state.snd_acked) if (ret != -ETIMEDOUT || acked == state.snd_acked)
{ {
if (ret == -ETIMEDOUT) if (ret == -ETIMEDOUT)
@@ -636,7 +639,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
} }
nxsem_destroy(&state.snd_sem); nxsem_destroy(&state.snd_sem);
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
/* Check for a errors. Errors are signalled by negative errno values /* Check for a errors. Errors are signalled by negative errno values
* for the send length * for the send length
+5 -2
View File
@@ -55,6 +55,7 @@
#include "icmpv6/icmpv6.h" #include "icmpv6/icmpv6.h"
#include "neighbor/neighbor.h" #include "neighbor/neighbor.h"
#include "socket/socket.h" #include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
#if defined(CONFIG_NET_SENDFILE) && defined(CONFIG_NET_TCP) && \ #if defined(CONFIG_NET_SENDFILE) && defined(CONFIG_NET_TCP) && \
@@ -475,7 +476,7 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile,
* ready. * ready.
*/ */
net_lock(); conn_dev_lock(&conn->sconn, conn->dev);
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS #ifdef CONFIG_NET_TCP_WRITE_BUFFERS
conn->sendfile = true; conn->sendfile = true;
#endif #endif
@@ -514,6 +515,7 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile,
TCP_DISCONN_EVENTS); TCP_DISCONN_EVENTS);
state.snd_cb->priv = (FAR void *)&state; state.snd_cb->priv = (FAR void *)&state;
state.snd_cb->event = sendfile_eventhandler; state.snd_cb->event = sendfile_eventhandler;
conn_dev_unlock(&conn->sconn, conn->dev);
/* Notify the device driver of the availability of TX data */ /* Notify the device driver of the availability of TX data */
@@ -536,6 +538,7 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile,
} }
} }
conn_dev_lock(&conn->sconn, conn->dev);
tcp_callback_free(conn, state.snd_cb); tcp_callback_free(conn, state.snd_cb);
errout_locked: errout_locked:
@@ -543,7 +546,7 @@ errout_locked:
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS #ifdef CONFIG_NET_TCP_WRITE_BUFFERS
conn->sendfile = false; conn->sendfile = false;
#endif #endif
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
/* Return the current file position */ /* Return the current file position */
+6 -4
View File
@@ -37,8 +37,9 @@
#include "netdev/netdev.h" #include "netdev/netdev.h"
#include "devif/devif.h" #include "devif/devif.h"
#include "tcp/tcp.h"
#include "socket/socket.h" #include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h"
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
@@ -105,11 +106,10 @@ static inline int tcp_send_fin(FAR struct socket *psock)
/* Interrupts are disabled here to avoid race conditions */ /* Interrupts are disabled here to avoid race conditions */
net_lock();
conn = psock->s_conn; conn = psock->s_conn;
DEBUGASSERT(conn != NULL); DEBUGASSERT(conn != NULL);
conn_dev_lock(&conn->sconn, conn->dev);
if ((conn->tcpstateflags == TCP_ESTABLISHED || if ((conn->tcpstateflags == TCP_ESTABLISHED ||
conn->tcpstateflags == TCP_SYN_SENT || conn->tcpstateflags == TCP_SYN_SENT ||
conn->tcpstateflags == TCP_SYN_RCVD || conn->tcpstateflags == TCP_SYN_RCVD ||
@@ -129,11 +129,13 @@ static inline int tcp_send_fin(FAR struct socket *psock)
/* Notify the device driver of the availability of TX data */ /* Notify the device driver of the availability of TX data */
conn_dev_unlock(&conn->sconn, conn->dev);
tcp_send_txnotify(psock, conn); tcp_send_txnotify(psock, conn);
return ret;
} }
out: out:
net_unlock(); conn_dev_unlock(&conn->sconn, conn->dev);
return ret; return ret;
} }
+9 -3
View File
@@ -62,6 +62,7 @@
#include "netdev/netdev.h" #include "netdev/netdev.h"
#include "devif/devif.h" #include "devif/devif.h"
#include "socket/socket.h" #include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h" #include "tcp/tcp.h"
/**************************************************************************** /****************************************************************************
@@ -145,19 +146,20 @@ static void tcp_timer_expiry(FAR void *arg)
{ {
FAR struct tcp_conn_s *conn = NULL; FAR struct tcp_conn_s *conn = NULL;
net_lock(); tcp_conn_list_lock();
while ((conn = tcp_nextconn(conn)) != NULL) while ((conn = tcp_nextconn(conn)) != NULL)
{ {
if (conn == arg) if (conn == arg)
{ {
tcp_conn_list_unlock();
conn->timeout = true; conn->timeout = true;
netdev_txnotify_dev(conn->dev); netdev_txnotify_dev(conn->dev);
break; return;
} }
} }
net_unlock(); tcp_conn_list_unlock();
} }
/**************************************************************************** /****************************************************************************
@@ -418,6 +420,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
* the connection. * the connection.
*/ */
conn_lock(&conn->sconn);
tcp_ip_select(conn); tcp_ip_select(conn);
hdrlen = tcpip_hdrsize(conn); hdrlen = tcpip_hdrsize(conn);
@@ -435,6 +438,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
{ {
/* Nothing to be done */ /* Nothing to be done */
conn_unlock(&conn->sconn);
return; return;
} }
@@ -537,6 +541,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
/* Finally, we must free this TCP connection structure */ /* Finally, we must free this TCP connection structure */
conn->crefs = 0; conn->crefs = 0;
conn_unlock(&conn->sconn);
tcp_free(conn); tcp_free(conn);
return; return;
} }
@@ -824,6 +829,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
done: done:
tcp_update_timer(conn); tcp_update_timer(conn);
conn_unlock(&conn->sconn);
} }
#endif /* CONFIG_NET && CONFIG_NET_TCP */ #endif /* CONFIG_NET && CONFIG_NET_TCP */
+4 -2
View File
@@ -104,7 +104,7 @@ int tcp_txdrain(FAR struct socket *psock, unsigned int timeout)
/* The following needs to be done with the network stable */ /* The following needs to be done with the network stable */
net_lock(); conn_lock(&conn->sconn);
/* Get a notification when the write buffers are drained */ /* Get a notification when the write buffers are drained */
@@ -145,7 +145,9 @@ int tcp_txdrain(FAR struct socket *psock, unsigned int timeout)
* wait for it to drain or be be disconnected. * wait for it to drain or be be disconnected.
*/ */
conn_dev_unlock(&conn->sconn, conn->dev);
ret = net_sem_timedwait_uninterruptible(&waitsem, timeout); ret = net_sem_timedwait_uninterruptible(&waitsem, timeout);
conn_dev_lock(&conn->sconn, conn->dev);
/* Tear down the disconnect notifier */ /* Tear down the disconnect notifier */
@@ -157,7 +159,7 @@ int tcp_txdrain(FAR struct socket *psock, unsigned int timeout)
tcp_notifier_teardown(drain_key); tcp_notifier_teardown(drain_key);
} }
net_unlock(); conn_unlock(&conn->sconn);
nxsem_destroy(&waitsem); nxsem_destroy(&waitsem);
return ret; return ret;
} }