udp: Use s_sndtimeo as the actual timeout time
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
parent
ef660083c8
commit
fc35cf4737
@ -472,6 +472,28 @@ struct udp_wrbuffer_s;
|
|||||||
FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void);
|
FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void);
|
||||||
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
|
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: udp_wrbuffer_timedalloc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate a UDP write buffer by taking a pre-allocated buffer from
|
||||||
|
* the free list. This function is called from udp logic when a buffer
|
||||||
|
* of udp data is about to sent
|
||||||
|
* This function is wrapped version of udp_wrbuffer_alloc(),
|
||||||
|
* this wait will be terminated when the specified timeout expires.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* timeout - The relative time to wait until a timeout is declared.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called from user logic with the network locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_UDP_WRITE_BUFFERS
|
||||||
|
FAR struct udp_wrbuffer_s *udp_wrbuffer_timedalloc(unsigned int timeout);
|
||||||
|
#endif /* CONFIG_NET_UDP_WRITE_BUFFERS */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: udp_wrbuffer_tryalloc
|
* Name: udp_wrbuffer_tryalloc
|
||||||
*
|
*
|
||||||
|
@ -501,6 +501,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
|||||||
{
|
{
|
||||||
FAR struct udp_wrbuffer_s *wrb;
|
FAR struct udp_wrbuffer_s *wrb;
|
||||||
FAR struct udp_conn_s *conn;
|
FAR struct udp_conn_s *conn;
|
||||||
|
unsigned int timeout;
|
||||||
bool nonblock;
|
bool nonblock;
|
||||||
bool empty;
|
bool empty;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
@ -628,6 +629,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
|||||||
|
|
||||||
nonblock = _SS_ISNONBLOCK(conn->sconn.s_flags) ||
|
nonblock = _SS_ISNONBLOCK(conn->sconn.s_flags) ||
|
||||||
(flags & MSG_DONTWAIT) != 0;
|
(flags & MSG_DONTWAIT) != 0;
|
||||||
|
timeout = _SO_TIMEOUT(conn->sconn.s_sndtimeo);
|
||||||
|
|
||||||
/* Dump the incoming buffer */
|
/* Dump the incoming buffer */
|
||||||
|
|
||||||
@ -650,7 +652,16 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
|||||||
goto errout_with_lock;
|
goto errout_with_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
net_lockedwait_uninterruptible(&conn->sndsem);
|
ret = net_timedwait_uninterruptible(&conn->sndsem, timeout);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (ret == -ETIMEDOUT)
|
||||||
|
{
|
||||||
|
ret = -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto errout_with_lock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_SEND_BUFSIZE */
|
#endif /* CONFIG_NET_SEND_BUFSIZE */
|
||||||
|
|
||||||
@ -664,7 +675,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wrb = udp_wrbuffer_alloc();
|
wrb = udp_wrbuffer_timedalloc(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrb == NULL)
|
if (wrb == NULL)
|
||||||
@ -672,7 +683,16 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
|||||||
/* A buffer allocation error occurred */
|
/* A buffer allocation error occurred */
|
||||||
|
|
||||||
nerr("ERROR: Failed to allocate write buffer\n");
|
nerr("ERROR: Failed to allocate write buffer\n");
|
||||||
ret = nonblock ? -EAGAIN : -ENOMEM;
|
|
||||||
|
if (nonblock || timeout != UINT_MAX)
|
||||||
|
{
|
||||||
|
ret = -EAGAIN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
goto errout_with_lock;
|
goto errout_with_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,11 +155,75 @@ FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void)
|
|||||||
return wrb;
|
return wrb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: udp_wrbuffer_timedalloc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate a UDP write buffer by taking a pre-allocated buffer from
|
||||||
|
* the free list. This function is called from udp logic when a buffer
|
||||||
|
* of udp data is about to sent
|
||||||
|
* This function is wrapped version of udp_wrbuffer_alloc(),
|
||||||
|
* this wait will be terminated when the specified timeout expires.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* timeout - The relative time to wait until a timeout is declared.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called from user logic with the network locked.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct udp_wrbuffer_s *udp_wrbuffer_timedalloc(unsigned int timeout)
|
||||||
|
{
|
||||||
|
FAR struct udp_wrbuffer_s *wrb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* We need to allocate two things: (1) A write buffer structure and (2)
|
||||||
|
* at least one I/O buffer to start the chain.
|
||||||
|
*
|
||||||
|
* Allocate the write buffer structure first then the IOB. In order to
|
||||||
|
* avoid deadlocks, we will need to free the IOB first, then the write
|
||||||
|
* buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = net_timedwait_uninterruptible(&g_wrbuffer.sem, timeout);
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now, we are guaranteed to have a write buffer structure reserved
|
||||||
|
* for us in the free list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
wrb = (FAR struct udp_wrbuffer_s *)sq_remfirst(&g_wrbuffer.freebuffers);
|
||||||
|
DEBUGASSERT(wrb);
|
||||||
|
memset(wrb, 0, sizeof(struct udp_wrbuffer_s));
|
||||||
|
|
||||||
|
/* Now get the first I/O buffer for the write buffer structure */
|
||||||
|
|
||||||
|
wrb->wb_iob = net_iobtimedalloc(true, timeout,
|
||||||
|
IOBUSER_NET_UDP_WRITEBUFFER);
|
||||||
|
|
||||||
|
/* Did we get an IOB? We should always get one except under some really
|
||||||
|
* weird error conditions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (wrb->wb_iob == NULL)
|
||||||
|
{
|
||||||
|
nerr("ERROR: Failed to allocate I/O buffer\n");
|
||||||
|
udp_wrbuffer_release(wrb);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrb;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: udp_wrbuffer_tryalloc
|
* Name: udp_wrbuffer_tryalloc
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Try to allocate a TCP write buffer by taking a pre-allocated buffer from
|
* Try to allocate a UDP write buffer by taking a pre-allocated buffer from
|
||||||
* the free list. This function is called from UDP logic when a buffer
|
* the free list. This function is called from UDP logic when a buffer
|
||||||
* of UDP data is about to be sent on a non-blocking socket. Returns
|
* of UDP data is about to be sent on a non-blocking socket. Returns
|
||||||
* immediately if the allocation failed.
|
* immediately if the allocation failed.
|
||||||
|
Loading…
Reference in New Issue
Block a user