mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 17:48:54 +08:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user