net/tcp: add interface tcp_wrbuffer_timedalloc()
add new interface to support alloc wrbuffer with timeout Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
a92d5f622e
commit
1911ae2192
@ -1548,6 +1548,30 @@ int psock_tcp_cansend(FAR struct tcp_conn_s *conn);
|
|||||||
void tcp_wrbuffer_initialize(void);
|
void tcp_wrbuffer_initialize(void);
|
||||||
#endif /* CONFIG_NET_TCP_WRITE_BUFFERS */
|
#endif /* CONFIG_NET_TCP_WRITE_BUFFERS */
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
|
||||||
|
|
||||||
|
struct tcp_wrbuffer_s;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: tcp_wrbuffer_timedalloc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate a TCP write buffer by taking a pre-allocated buffer from
|
||||||
|
* the free list. This function is called from TCP logic when a buffer
|
||||||
|
* of TCP data is about to sent
|
||||||
|
* This function is wrapped version of tcp_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 tcp_wrbuffer_s *tcp_wrbuffer_timedalloc(unsigned int timeout);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: tcp_wrbuffer_alloc
|
* Name: tcp_wrbuffer_alloc
|
||||||
*
|
*
|
||||||
@ -1564,8 +1588,6 @@ void tcp_wrbuffer_initialize(void);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
|
|
||||||
struct tcp_wrbuffer_s;
|
|
||||||
FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void);
|
FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -105,6 +105,70 @@ void tcp_wrbuffer_initialize(void)
|
|||||||
nxsem_set_protocol(&g_wrbuffer.sem, SEM_PRIO_NONE);
|
nxsem_set_protocol(&g_wrbuffer.sem, SEM_PRIO_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: tcp_wrbuffer_timedalloc
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate a TCP write buffer by taking a pre-allocated buffer from
|
||||||
|
* the free list. This function is called from TCP logic when a buffer
|
||||||
|
* of TCP data is about to sent
|
||||||
|
* This function is wrapped version of tcp_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 tcp_wrbuffer_s *tcp_wrbuffer_timedalloc(unsigned int timeout)
|
||||||
|
{
|
||||||
|
FAR struct tcp_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 tcp_wrbuffer_s *)sq_remfirst(&g_wrbuffer.freebuffers);
|
||||||
|
DEBUGASSERT(wrb);
|
||||||
|
memset(wrb, 0, sizeof(struct tcp_wrbuffer_s));
|
||||||
|
|
||||||
|
/* Now get the first I/O buffer for the write buffer structure */
|
||||||
|
|
||||||
|
wrb->wb_iob = net_iobtimedalloc(true, timeout,
|
||||||
|
IOBUSER_NET_TCP_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");
|
||||||
|
tcp_wrbuffer_release(wrb);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrb;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: tcp_wrbuffer_alloc
|
* Name: tcp_wrbuffer_alloc
|
||||||
*
|
*
|
||||||
@ -123,42 +187,7 @@ void tcp_wrbuffer_initialize(void)
|
|||||||
|
|
||||||
FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void)
|
FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void)
|
||||||
{
|
{
|
||||||
FAR struct tcp_wrbuffer_s *wrb;
|
return tcp_wrbuffer_timedalloc(UINT_MAX);
|
||||||
|
|
||||||
/* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
net_lockedwait_uninterruptible(&g_wrbuffer.sem);
|
|
||||||
|
|
||||||
/* Now, we are guaranteed to have a write buffer structure reserved
|
|
||||||
* for us in the free list.
|
|
||||||
*/
|
|
||||||
|
|
||||||
wrb = (FAR struct tcp_wrbuffer_s *)sq_remfirst(&g_wrbuffer.freebuffers);
|
|
||||||
DEBUGASSERT(wrb);
|
|
||||||
memset(wrb, 0, sizeof(struct tcp_wrbuffer_s));
|
|
||||||
|
|
||||||
/* Now get the first I/O buffer for the write buffer structure */
|
|
||||||
|
|
||||||
wrb->wb_iob = net_ioballoc(true, IOBUSER_NET_TCP_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");
|
|
||||||
tcp_wrbuffer_release(wrb);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wrb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -181,40 +210,7 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void)
|
|||||||
|
|
||||||
FAR struct tcp_wrbuffer_s *tcp_wrbuffer_tryalloc(void)
|
FAR struct tcp_wrbuffer_s *tcp_wrbuffer_tryalloc(void)
|
||||||
{
|
{
|
||||||
FAR struct tcp_wrbuffer_s *wrb;
|
return tcp_wrbuffer_timedalloc(0);
|
||||||
|
|
||||||
/* 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 IOBG. In order to
|
|
||||||
* avoid deadlocks, we will need to free the IOB first, then the write
|
|
||||||
* buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (nxsem_trywait(&g_wrbuffer.sem) != OK)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now, we are guaranteed to have a write buffer structure reserved
|
|
||||||
* for us in the free list.
|
|
||||||
*/
|
|
||||||
|
|
||||||
wrb = (FAR struct tcp_wrbuffer_s *)sq_remfirst(&g_wrbuffer.freebuffers);
|
|
||||||
DEBUGASSERT(wrb);
|
|
||||||
memset(wrb, 0, sizeof(struct tcp_wrbuffer_s));
|
|
||||||
|
|
||||||
/* Now get the first I/O buffer for the write buffer structure */
|
|
||||||
|
|
||||||
wrb->wb_iob = iob_tryalloc(false, IOBUSER_NET_TCP_WRITEBUFFER);
|
|
||||||
if (!wrb->wb_iob)
|
|
||||||
{
|
|
||||||
nerr("ERROR: Failed to allocate I/O buffer\n");
|
|
||||||
tcp_wrbuffer_release(wrb);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wrb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user