This is an automated email from the ASF dual-hosted git repository. pkarashchenko pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 1911ae219255ab34a7b19c299b378838116e7de1 Author: chao.an <anc...@xiaomi.com> AuthorDate: Thu Feb 17 12:58:00 2022 +0800 net/tcp: add interface tcp_wrbuffer_timedalloc() add new interface to support alloc wrbuffer with timeout Signed-off-by: chao.an <anc...@xiaomi.com> --- net/tcp/tcp.h | 26 ++++++++++++++++-- net/tcp/tcp_wrbuffer.c | 74 ++++++++++++++++++++++++-------------------------- 2 files changed, 59 insertions(+), 41 deletions(-) diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 87dab15..030a52b 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -1548,6 +1548,30 @@ int psock_tcp_cansend(FAR struct tcp_conn_s *conn); void tcp_wrbuffer_initialize(void); #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 * @@ -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); /**************************************************************************** diff --git a/net/tcp/tcp_wrbuffer.c b/net/tcp/tcp_wrbuffer.c index a93a2bc..7fb1bec 100644 --- a/net/tcp/tcp_wrbuffer.c +++ b/net/tcp/tcp_wrbuffer.c @@ -106,24 +106,27 @@ void tcp_wrbuffer_initialize(void) } /**************************************************************************** - * Name: tcp_wrbuffer_alloc + * 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: - * None + * 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_alloc(void) +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. @@ -133,7 +136,11 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void) * buffer */ - net_lockedwait_uninterruptible(&g_wrbuffer.sem); + 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. @@ -145,7 +152,8 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void) /* Now get the first I/O buffer for the write buffer structure */ - wrb->wb_iob = net_ioballoc(true, IOBUSER_NET_TCP_WRITEBUFFER); + 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. @@ -162,6 +170,27 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void) } /**************************************************************************** + * Name: tcp_wrbuffer_alloc + * + * 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 + * + * Input Parameters: + * None + * + * Assumptions: + * Called from user logic with the network locked. + * + ****************************************************************************/ + +FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void) +{ + return tcp_wrbuffer_timedalloc(UINT_MAX); +} + +/**************************************************************************** * Name: tcp_wrbuffer_tryalloc * * Description: @@ -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 *wrb; - - /* 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; + return tcp_wrbuffer_timedalloc(0); } /****************************************************************************