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 *raddr;
net_lock();
while ((conn = tcp_nextconn(conn)) != NULL)
{
#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));
}
net_unlock();
return len;
}
@@ -158,7 +154,7 @@ ssize_t netprocfs_read_tcpstats(FAR struct netprocfs_file_s *priv,
int skip = 1;
int len = 0;
net_lock();
tcp_conn_list_lock();
if (tcp_nextconn(NULL) != NULL)
{
@@ -192,7 +188,7 @@ ssize_t netprocfs_read_tcpstats(FAR struct netprocfs_file_s *priv,
#endif /* CONFIG_NET_IPv6 */
}
net_unlock();
tcp_conn_list_unlock();
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);
/****************************************************************************
* 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
*
+14 -5
View File
@@ -39,6 +39,7 @@
#include <nuttx/net/net.h>
#include "socket/socket.h"
#include "utils/utils.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;
struct accept_s state;
int ret;
int ret = OK;
/* Check the backlog to see if there is a connection already pending for
* this listener.
@@ -225,6 +226,8 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
conn = psock->s_conn;
conn_lock(&conn->sconn);
#ifdef CONFIG_NET_TCPBACKLOG
state.acpt_newconn = tcp_backlogremove(conn);
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))
{
return -EAGAIN;
ret = -EAGAIN;
goto out;
}
else
#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.
*/
conn_unlock(&conn->sconn);
ret = net_sem_wait(&state.acpt_sem);
conn_lock(&conn->sconn);
/* 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)
{
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
@@ -297,12 +303,15 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
if (ret < 0)
{
return ret;
goto out;
}
}
*newconn = (FAR void *)state.acpt_newconn;
return OK;
out:
conn_unlock(&conn->sconn);
return ret;
}
#endif /* CONFIG_NET_TCP */
+3 -2
View File
@@ -37,6 +37,7 @@
#include <nuttx/net/net.h>
#include "devif/devif.h"
#include "utils/utils.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) */
net_lock();
conn_lock(&conn->sconn);
tcp_backlogdestroy(conn);
/* 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;
net_unlock();
conn_unlock(&conn->sconn);
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)
{
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");
tcp_callback_free(cb->tc_conn, *(cb->tc_cb));
nxsem_destroy(cb->tc_sem);
net_unlock();
conn_dev_unlock(&conn->sconn, conn->dev);
}
#endif /* NET_TCP_HAVE_STACK */
+7 -7
View File
@@ -40,6 +40,7 @@
#include "devif/devif.h"
#include "tcp/tcp.h"
#include "socket/socket.h"
#include "utils/utils.h"
/****************************************************************************
* 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;
net_lock();
conn->flags &= ~TCP_CLOSE_ARRANGED;
if (conn->crefs == 0)
{
/* Stop the network monitor for all sockets */
conn_dev_lock(&conn->sconn, conn->dev);
tcp_stop_monitor(conn, TCP_CLOSE);
conn_dev_unlock(&conn->sconn, conn->dev);
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 */
net_lock();
conn = psock->s_conn;
conn_dev_lock(&conn->sconn, conn->dev);
/* Discard our reference to the connection */
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 */
tcp_send_txnotify(psock, conn);
conn_dev_unlock(&conn->sconn, conn->dev);
}
else
{
/* Stop the network monitor for all sockets */
tcp_stop_monitor(conn, TCP_CLOSE);
conn_dev_unlock(&conn->sconn, conn->dev);
/* Free network resources */
@@ -293,7 +294,6 @@ static inline int tcp_close_disconnect(FAR struct socket *psock)
psock->s_conn = NULL;
net_unlock();
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 */
net_lock();
if (conn->lport != 0)
{
net_unlock();
return -EINVAL;
}
@@ -372,7 +369,6 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
if (ret == -EADDRNOTAVAIL)
{
net_unlock();
return ret;
}
}
@@ -385,7 +381,6 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
if (port < 0)
{
nerr("ERROR: tcp_selectport failed: %d\n", port);
net_unlock();
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_unlock();
return ret;
}
#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 */
net_lock();
if (conn->lport != 0)
{
net_unlock();
return -EINVAL;
}
@@ -472,7 +463,6 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
netdev_list_unlock();
if (ret == -EADDRNOTAVAIL)
{
net_unlock();
return ret;
}
}
@@ -487,7 +477,6 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
if (port < 0)
{
nerr("ERROR: tcp_selectport failed: %d\n", port);
net_unlock();
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_unlock();
return ret;
}
#endif /* CONFIG_NET_IPv6 */
@@ -561,6 +549,7 @@ int tcp_selectport(uint8_t domain,
NET_PORT_RANDOM_INIT(g_last_tcp_port);
}
tcp_conn_list_lock();
if (portno == 0)
{
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) */
tcp_conn_list_unlock();
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[];
*/
net_lock();
tcp_conn_list_lock();
/* 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
net_unlock();
tcp_conn_list_unlock();
/* 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);
#endif
nxmutex_init(&conn->sconn.s_lock);
/* Set the default value of mss to max, this field will changed when
* receive SYN.
@@ -815,13 +806,6 @@ void tcp_free(FAR struct tcp_conn_s *conn)
FAR struct tcp_wrbuffer_s *wrbuffer;
#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);
/* 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. */
net_unlock();
return;
}
@@ -841,6 +824,7 @@ void tcp_free(FAR struct tcp_conn_s *conn)
/* Make sure monitor is stopped. */
conn_dev_lock(&conn->sconn, conn->dev);
tcp_stop_monitor(conn, TCP_CLOSE);
/* 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);
}
conn_dev_unlock(&conn->sconn, conn->dev);
/* TCP_ALLOCATED means that that the connection is not in the active list
* yet.
*/
@@ -861,9 +847,12 @@ void tcp_free(FAR struct tcp_conn_s *conn)
{
/* Remove the connection from the active list */
tcp_conn_list_lock();
dq_rem(&conn->sconn.node, &g_active_tcp_connections);
tcp_conn_list_unlock();
}
nxmutex_destroy(&conn->sconn.s_lock);
tcp_free_rx_buffers(conn);
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
@@ -918,8 +907,6 @@ void tcp_free(FAR struct tcp_conn_s *conn)
/* Free the connection structure */
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_hdr_s *tcp)
{
FAR struct tcp_conn_s *conn = NULL;
tcp_conn_list_lock();
#ifdef CONFIG_NET_IPv6
#ifdef CONFIG_NET_IPv4
if (IFF_IS_IPv6(dev->d_flags))
#endif
{
return tcp_ipv6_active(dev, tcp);
conn = tcp_ipv6_active(dev, tcp);
}
#endif /* CONFIG_NET_IPv6 */
@@ -951,9 +941,12 @@ FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev,
else
#endif
{
return tcp_ipv4_active(dev, tcp);
conn = tcp_ipv4_active(dev, tcp);
}
#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.
*/
tcp_conn_list_lock();
dq_addlast(&conn->sconn.node, &g_active_tcp_connections);
tcp_conn_list_unlock();
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 port;
int ret = OK;
int ret;
/* 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
@@ -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.
*/
net_lock();
/* Check if the local port has been bind() */
port = conn->lport;
@@ -1302,8 +1296,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
if (port < 0)
{
ret = port;
goto errout_with_lock;
return port;
}
}
@@ -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);
goto errout_with_lock;
return ret;
}
#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)
{
ret = -ENETUNREACH;
goto errout_with_lock;
return -ENETUNREACH;
}
#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. */
tcp_conn_list_lock();
dq_addlast(&conn->sconn.node, &g_active_tcp_connections);
ret = OK;
tcp_conn_list_unlock();
errout_with_lock:
net_unlock();
return ret;
return OK;
}
/****************************************************************************
* 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)
{
net_lock();
dq_rem(&conn->sconn.node, &g_active_tcp_connections);
net_unlock();
}
#endif /* CONFIG_NET && CONFIG_NET_TCP */
+6 -3
View File
@@ -47,6 +47,7 @@
#include "netdev/netdev.h"
#include "socket/socket.h"
#include "inet/inet.h"
#include "utils/utils.h"
#include "tcp/tcp.h"
#ifdef NET_TCP_HAVE_STACK
@@ -304,8 +305,6 @@ int psock_tcp_connect(FAR struct socket *psock,
* setup.
*/
net_lock();
conn = psock->s_conn;
/* 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 */
conn_dev_lock(&conn->sconn, conn->dev);
ret = psock_setup_callbacks(psock, &state);
if (ret >= 0)
{
@@ -377,6 +377,7 @@ int psock_tcp_connect(FAR struct socket *psock,
info.tc_conn = conn;
info.tc_cb = &state.tc_cb;
info.tc_sem = &state.tc_sem;
conn_dev_unlock(&conn->sconn, conn->dev);
tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info);
/* 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);
tls_cleanup_pop(tls_get_info(), 0);
conn_dev_lock(&conn->sconn, conn->dev);
/* Uninitialize the state structure */
@@ -412,6 +414,8 @@ int psock_tcp_connect(FAR struct socket *psock,
psock_teardown_callbacks(&state, ret);
}
conn_dev_unlock(&conn->sconn, conn->dev);
}
/* Check if the socket was successfully connected. */
@@ -443,7 +447,6 @@ int psock_tcp_connect(FAR struct socket *psock,
}
}
net_unlock();
return ret;
}
+3
View File
@@ -55,6 +55,7 @@
#include <nuttx/net/tcp.h>
#include "devif/devif.h"
#include "utils/utils.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.
*/
conn_lock(&conn->sconn);
tcp_ip_select(conn);
/* 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 */
tcp_appsend(dev, conn, result);
conn_unlock(&conn->sconn);
}
}
+3 -2
View File
@@ -38,6 +38,7 @@
#include <nuttx/mm/iob.h>
#include <nuttx/net/net.h>
#include "utils/utils.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;
net_lock();
conn_lock(&conn->sconn);
switch (cmd)
{
@@ -156,7 +157,7 @@ int tcp_ioctl(FAR struct tcp_conn_s *conn, int cmd, unsigned long arg)
break;
}
net_unlock();
conn_unlock(&conn->sconn);
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 */
tcp_conn_list_lock();
for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++)
{
/* 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 */
tcp_conn_list_unlock();
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 */
tcp_conn_list_unlock();
return conn;
}
}
@@ -142,6 +145,7 @@ FAR struct tcp_conn_s *tcp_findlistener(FAR union ip_binding_u *uaddr,
/* No listener for this port */
tcp_conn_list_unlock();
return NULL;
}
@@ -165,7 +169,7 @@ int tcp_unlisten(FAR struct tcp_conn_s *conn)
int ndx;
int ret = -EINVAL;
net_lock();
tcp_conn_list_lock();
for (ndx = 0; ndx < CONFIG_NET_MAX_LISTENPORTS; ndx++)
{
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;
}
@@ -200,7 +204,7 @@ int tcp_listen(FAR struct tcp_conn_s *conn)
* 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 */
@@ -239,7 +243,7 @@ int tcp_listen(FAR struct tcp_conn_s *conn)
}
}
net_unlock();
tcp_conn_list_unlock();
return ret;
}
+3 -9
View File
@@ -34,6 +34,7 @@
#include "devif/devif.h"
#include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h"
#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.
*/
net_lock();
/* Free all allocated connection event callback structures */
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_tail);
}
net_unlock();
}
/****************************************************************************
@@ -250,8 +247,6 @@ int tcp_start_monitor(FAR struct socket *psock)
conn = psock->s_conn;
net_lock();
/* Non-blocking connection ? */
nonblock_conn = (conn->tcpstateflags == TCP_SYN_SENT &&
@@ -277,7 +272,6 @@ int tcp_start_monitor(FAR struct socket *psock)
if (conn->tcpstateflags == TCP_CLOSED ||
conn->tcpstateflags == TCP_LAST_ACK)
{
net_unlock();
return OK;
}
@@ -285,7 +279,6 @@ int tcp_start_monitor(FAR struct socket *psock)
* because the socket was already disconnected.
*/
net_unlock();
return -ENOTCONN;
}
@@ -293,6 +286,7 @@ int tcp_start_monitor(FAR struct socket *psock)
* the network goes down.
*/
conn_dev_lock(&conn->sconn, conn->dev);
cb = devif_callback_alloc(conn->dev,
&conn->connevents,
&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;
}
+8 -9
View File
@@ -39,6 +39,7 @@
#include "netdev/netdev.h"
#include "socket/socket.h"
#include "inet/inet.h"
#include "utils/utils.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 */
net_lock();
conn = psock->s_conn;
/* Sanity check */
if (!conn || !fds)
{
ret = -EINVAL;
goto errout_with_lock;
return -EINVAL;
}
conn_dev_lock(&conn->sconn, conn->dev);
/* Non-blocking connection ? */
nonblock_conn = ((conn->tcpstateflags == TCP_ALLOCATED ||
@@ -388,7 +388,7 @@ notify:
poll_notify(&fds, 1, eventset);
errout_with_lock:
net_unlock();
conn_dev_unlock(&conn->sconn, conn->dev);
return ret;
}
@@ -415,18 +415,17 @@ int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds)
/* Some of the following must be atomic */
net_lock();
conn = psock->s_conn;
/* Sanity check */
if (!conn || !fds->priv)
{
net_unlock();
return -EINVAL;
}
conn_dev_lock(&conn->sconn, conn->dev);
/* Recover the socket descriptor poll state info from the poll structure */
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;
}
net_unlock();
conn_dev_unlock(&conn->sconn, conn->dev);
return OK;
}
+8 -4
View File
@@ -42,8 +42,9 @@
#include "netdev/netdev.h"
#include "devif/devif.h"
#include "tcp/tcp.h"
#include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h"
/****************************************************************************
* 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_cb = &state.ir_cb;
info.tc_sem = &state.ir_sem;
conn_dev_unlock(&conn->sconn, conn->dev);
tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info);
/* 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,
_SO_TIMEOUT(conn->sconn.s_rcvtimeo));
tls_cleanup_pop(tls_get_info(), 0);
conn_dev_lock(&conn->sconn, conn->dev);
if (ret == -ETIMEDOUT)
{
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))
{
conn_unlock(&conn->sconn);
netdev_txnotify_dev(conn->dev);
conn_lock(&conn->sconn);
}
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;
int i;
net_lock();
conn = psock->s_conn;
conn_dev_lock(&conn->sconn, conn->dev);
for (i = 0; i < msg->msg_iovlen; i++)
{
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;
}
+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;
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
* 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_cb = &conn->sndcb;
info.tc_sem = &conn->snd_sem;
conn_dev_unlock(&conn->sconn, conn->dev);
tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info);
ret = net_sem_timedwait_uninterruptible(&conn->snd_sem,
tcp_send_gettimeout(start, timeout));
tls_cleanup_pop(tls_get_info(), 0);
conn_dev_lock(&conn->sconn, conn->dev);
if (ret < 0)
{
if (ret == -ETIMEDOUT)
@@ -1523,8 +1525,10 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
}
else
{
conn_dev_unlock(&conn->sconn, conn->dev);
wrb = tcp_wrbuffer_timedalloc(tcp_send_gettimeout(start,
timeout));
conn_dev_lock(&conn->sconn, conn->dev);
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.
*/
conn_dev_unlock(&conn->sconn, conn->dev);
iob = net_iobtimedalloc(true, tcp_send_gettimeout(start, timeout));
conn_dev_lock(&conn->sconn, conn->dev);
if (iob != NULL)
{
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 */
conn_dev_unlock(&conn->sconn, conn->dev);
tcp_send_txnotify(psock, conn);
net_unlock();
if (chunk_result == 0)
{
@@ -1699,7 +1705,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
return result;
errout_with_lock:
net_unlock();
conn_dev_unlock(&conn->sconn, conn->dev);
errout:
if (result > 0)
+6 -3
View File
@@ -55,6 +55,7 @@
#include "icmpv6/icmpv6.h"
#include "neighbor/neighbor.h"
#include "route/route.h"
#include "utils/utils.h"
#include "tcp/tcp.h"
/****************************************************************************
@@ -548,7 +549,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
* ready.
*/
net_lock();
conn_dev_lock(&conn->sconn, conn->dev);
/* Now that we have the network locked, we need to check the connection
* 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))
{
nerr("ERROR: No longer connected\n");
net_unlock();
conn_dev_unlock(&conn->sconn, conn->dev);
ret = -ENOTCONN;
goto errout;
}
@@ -613,11 +614,13 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
info.tc_conn = conn;
info.tc_cb = &state.snd_cb;
info.tc_sem = &state.snd_sem;
conn_dev_unlock(&conn->sconn, conn->dev);
tls_cleanup_push(tls_get_info(), tcp_callback_cleanup, &info);
ret = net_sem_timedwait(&state.snd_sem,
_SO_TIMEOUT(conn->sconn.s_sndtimeo));
tls_cleanup_pop(tls_get_info(), 0);
conn_dev_lock(&conn->sconn, conn->dev);
if (ret != -ETIMEDOUT || acked == state.snd_acked)
{
if (ret == -ETIMEDOUT)
@@ -636,7 +639,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock,
}
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
* for the send length
+5 -2
View File
@@ -55,6 +55,7 @@
#include "icmpv6/icmpv6.h"
#include "neighbor/neighbor.h"
#include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h"
#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.
*/
net_lock();
conn_dev_lock(&conn->sconn, conn->dev);
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
conn->sendfile = true;
#endif
@@ -514,6 +515,7 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile,
TCP_DISCONN_EVENTS);
state.snd_cb->priv = (FAR void *)&state;
state.snd_cb->event = sendfile_eventhandler;
conn_dev_unlock(&conn->sconn, conn->dev);
/* 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);
errout_locked:
@@ -543,7 +546,7 @@ errout_locked:
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
conn->sendfile = false;
#endif
net_unlock();
conn_dev_unlock(&conn->sconn, conn->dev);
/* Return the current file position */
+6 -4
View File
@@ -37,8 +37,9 @@
#include "netdev/netdev.h"
#include "devif/devif.h"
#include "tcp/tcp.h"
#include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h"
/****************************************************************************
* Private Functions
@@ -105,11 +106,10 @@ static inline int tcp_send_fin(FAR struct socket *psock)
/* Interrupts are disabled here to avoid race conditions */
net_lock();
conn = psock->s_conn;
DEBUGASSERT(conn != NULL);
conn_dev_lock(&conn->sconn, conn->dev);
if ((conn->tcpstateflags == TCP_ESTABLISHED ||
conn->tcpstateflags == TCP_SYN_SENT ||
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 */
conn_dev_unlock(&conn->sconn, conn->dev);
tcp_send_txnotify(psock, conn);
return ret;
}
out:
net_unlock();
conn_dev_unlock(&conn->sconn, conn->dev);
return ret;
}
+9 -3
View File
@@ -62,6 +62,7 @@
#include "netdev/netdev.h"
#include "devif/devif.h"
#include "socket/socket.h"
#include "utils/utils.h"
#include "tcp/tcp.h"
/****************************************************************************
@@ -145,19 +146,20 @@ static void tcp_timer_expiry(FAR void *arg)
{
FAR struct tcp_conn_s *conn = NULL;
net_lock();
tcp_conn_list_lock();
while ((conn = tcp_nextconn(conn)) != NULL)
{
if (conn == arg)
{
tcp_conn_list_unlock();
conn->timeout = true;
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.
*/
conn_lock(&conn->sconn);
tcp_ip_select(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 */
conn_unlock(&conn->sconn);
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 */
conn->crefs = 0;
conn_unlock(&conn->sconn);
tcp_free(conn);
return;
}
@@ -824,6 +829,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
done:
tcp_update_timer(conn);
conn_unlock(&conn->sconn);
}
#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 */
net_lock();
conn_lock(&conn->sconn);
/* 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.
*/
conn_dev_unlock(&conn->sconn, conn->dev);
ret = net_sem_timedwait_uninterruptible(&waitsem, timeout);
conn_dev_lock(&conn->sconn, conn->dev);
/* Tear down the disconnect notifier */
@@ -157,7 +159,7 @@ int tcp_txdrain(FAR struct socket *psock, unsigned int timeout)
tcp_notifier_teardown(drain_key);
}
net_unlock();
conn_unlock(&conn->sconn);
nxsem_destroy(&waitsem);
return ret;
}