You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/02/17 20:27:50 UTC

[incubator-nuttx] 02/02: net/tcp: add interface tcp_wrbuffer_timedalloc()

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 <an...@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 <an...@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);
 }
 
 /****************************************************************************