You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/02/19 18:12:01 UTC

[incubator-nuttx] branch pr313 updated: net/socket: add MSG_DONTWAIT support

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch pr313
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/pr313 by this push:
     new d25b1cb  net/socket: add MSG_DONTWAIT support
d25b1cb is described below

commit d25b1cb1da9168303046bbd8f6ec692e4a89ba71
Author: chao.an <an...@xiaomi.com>
AuthorDate: Wed Feb 5 15:48:17 2020 +0800

    net/socket: add MSG_DONTWAIT support
    
    MSG_DONTWAIT (since Linux 2.2)
      Enables nonblocking operation; if the operation would block, the
      call fails with the error EAGAIN or EWOULDBLOCK. This provides
      similar behavior to setting the O_NONBLOCK flag (via the fcntl(2)
      F_SETFL operation), but differs in that MSG_DONTWAIT is a per-call
      option, whereas O_NONBLOCK is a setting on the open file description
      (see open(2)), which will affect all threads in the calling process
      and as well as other processes that hold file descriptors referring
      to the same open file description.
    
    Change-Id: Ide4d40b527c30d4a99b99b2d607a15462efe5f0c
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 net/inet/inet_sockif.c         |  8 ++++----
 net/local/local_recvfrom.c     |  3 ++-
 net/local/local_sendto.c       |  3 ++-
 net/netlink/netlink_route.c    |  2 +-
 net/tcp/tcp.h                  | 15 +++++++++------
 net/tcp/tcp_recvfrom.c         | 14 ++++++++------
 net/tcp/tcp_send_buffered.c    | 14 +++++++++-----
 net/tcp/tcp_send_unbuffered.c  |  3 ++-
 net/udp/udp.h                  | 12 +++++++-----
 net/udp/udp_recvfrom.c         |  4 ++--
 net/udp/udp_sendto_buffered.c  |  9 ++++++---
 net/usrsock/usrsock_recvfrom.c |  2 +-
 net/usrsock/usrsock_sendto.c   |  2 +-
 13 files changed, 54 insertions(+), 37 deletions(-)

diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c
index 27f2acf..900983e 100644
--- a/net/inet/inet_sockif.c
+++ b/net/inet/inet_sockif.c
@@ -1076,11 +1076,11 @@ static ssize_t inet_send(FAR struct socket *psock, FAR const void *buf,
             {
               /* TCP/IP packet send */
 
-              ret = psock_tcp_send(psock, buf, len);
+              ret = psock_tcp_send(psock, buf, len, flags);
             }
 #endif /* NET_TCP_HAVE_STACK */
 #elif defined(NET_TCP_HAVE_STACK)
-          ret = psock_tcp_send(psock, buf, len);
+          ret = psock_tcp_send(psock, buf, len, flags);
 #else
           ret = -ENOSYS;
 #endif /* CONFIG_NET_6LOWPAN */
@@ -1348,7 +1348,7 @@ static ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf,
     case SOCK_STREAM:
       {
 #ifdef NET_TCP_HAVE_STACK
-        ret = psock_tcp_recvfrom(psock, buf, len, from, fromlen);
+        ret = psock_tcp_recvfrom(psock, buf, len, flags, from, fromlen);
 #else
         ret = -ENOSYS;
 #endif
@@ -1360,7 +1360,7 @@ static ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf,
     case SOCK_DGRAM:
       {
 #ifdef NET_UDP_HAVE_STACK
-        ret = psock_udp_recvfrom(psock, buf, len, from, fromlen);
+        ret = psock_udp_recvfrom(psock, buf, len, flags, from, fromlen);
 #else
         ret = -ENOSYS;
 #endif
diff --git a/net/local/local_recvfrom.c b/net/local/local_recvfrom.c
index c34e9e0..45fb7d7 100644
--- a/net/local/local_recvfrom.c
+++ b/net/local/local_recvfrom.c
@@ -279,7 +279,8 @@ psock_dgram_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
 
   /* Open the receiving side of the transfer */
 
-  ret = local_open_receiver(conn, _SS_ISNONBLOCK(psock->s_flags));
+  ret = local_open_receiver(conn, _SS_ISNONBLOCK(psock->s_flags) ||
+                            (flags & MSG_DONTWAIT) != 0);
   if (ret < 0)
     {
       nerr("ERROR: Failed to open FIFO for %s: %d\n",
diff --git a/net/local/local_sendto.c b/net/local/local_sendto.c
index 4ac35b4..8db7c01 100644
--- a/net/local/local_sendto.c
+++ b/net/local/local_sendto.c
@@ -138,7 +138,8 @@ ssize_t psock_local_sendto(FAR struct socket *psock, FAR const void *buf,
   /* Open the sending side of the transfer */
 
   ret = local_open_sender(conn, unaddr->sun_path,
-                          _SS_ISNONBLOCK(psock->s_flags));
+                          _SS_ISNONBLOCK(psock->s_flags) ||
+                          (flags & MSG_DONTWAIT) != 0);
   if (ret < 0)
     {
       nerr("ERROR: Failed to open FIFO for %s: %d\n",
diff --git a/net/netlink/netlink_route.c b/net/netlink/netlink_route.c
index 0b0984b..ef4b808 100644
--- a/net/netlink/netlink_route.c
+++ b/net/netlink/netlink_route.c
@@ -1058,7 +1058,7 @@ ssize_t netlink_route_recvfrom(FAR struct socket *psock,
        * select Netlink non-blocking sockets.
        */
 
-      if (_SS_ISNONBLOCK(psock->s_flags))
+      if (_SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0)
         {
           return -EAGAIN;
         }
diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h
index 39727f8..32cea07 100644
--- a/net/tcp/tcp.h
+++ b/net/tcp/tcp.h
@@ -1274,10 +1274,12 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
  *   Perform the recvfrom operation for a TCP/IP SOCK_STREAM
  *
  * Input Parameters:
- *   psock  Pointer to the socket structure for the SOCK_DRAM socket
- *   buf    Buffer to receive data
- *   len    Length of buffer
- *   from   INET address of source (may be NULL)
+ *   psock    Pointer to the socket structure for the SOCK_DRAM socket
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   flags    Receive flags
+ *   from     INET address of source (may be NULL)
+ *   fromlen  The length of the address structure
  *
  * Returned Value:
  *   On success, returns the number of characters received.  On  error,
@@ -1288,7 +1290,7 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
  ****************************************************************************/
 
 ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR void *buf,
-                           size_t len, FAR struct sockaddr *from,
+                           size_t len, int flags, FAR struct sockaddr *from,
                            FAR socklen_t *fromlen);
 
 /****************************************************************************
@@ -1302,6 +1304,7 @@ ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR void *buf,
  *   psock    An instance of the internal socket structure.
  *   buf      Data to send
  *   len      Length of data to send
+ *   flags    Send flags
  *
  * Returned Value:
  *   On success, returns the number of characters sent.  On  error,
@@ -1350,7 +1353,7 @@ ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR void *buf,
 
 struct socket;
 ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
-                       size_t len);
+                       size_t len, int flags);
 
 /****************************************************************************
  * Name: tcp_setsockopt
diff --git a/net/tcp/tcp_recvfrom.c b/net/tcp/tcp_recvfrom.c
index dba3acf..9c050e1 100644
--- a/net/tcp/tcp_recvfrom.c
+++ b/net/tcp/tcp_recvfrom.c
@@ -628,10 +628,12 @@ static ssize_t tcp_recvfrom_result(int result, struct tcp_recvfrom_s *pstate)
  *   Perform the recvfrom operation for a TCP/IP SOCK_STREAM
  *
  * Input Parameters:
- *   psock  Pointer to the socket structure for the SOCK_DRAM socket
- *   buf    Buffer to receive data
- *   len    Length of buffer
- *   from   INET address of source (may be NULL)
+ *   psock    Pointer to the socket structure for the SOCK_DRAM socket
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   flags    Receive flags
+ *   from     INET address of source (may be NULL)
+ *   fromlen  The length of the address structure
  *
  * Returned Value:
  *   On success, returns the number of characters received.  On  error,
@@ -642,7 +644,7 @@ static ssize_t tcp_recvfrom_result(int result, struct tcp_recvfrom_s *pstate)
  ****************************************************************************/
 
 ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR void *buf,
-                           size_t len, FAR struct sockaddr *from,
+                           size_t len, int flags, FAR struct sockaddr *from,
                            FAR socklen_t *fromlen)
 {
   struct tcp_recvfrom_s state;
@@ -702,7 +704,7 @@ ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR void *buf,
    * if no data was obtained from the read-ahead buffers.
    */
 
-  else if (_SS_ISNONBLOCK(psock->s_flags))
+  else if (_SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0)
     {
       /* Return the number of bytes read from the read-ahead buffer if
        * something was received (already in 'ret'); EAGAIN if not.
diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c
index 76d4af2..78d535b 100644
--- a/net/tcp/tcp_send_buffered.c
+++ b/net/tcp/tcp_send_buffered.c
@@ -886,6 +886,7 @@ static inline void send_txnotify(FAR struct socket *psock,
  *   psock    An instance of the internal socket structure.
  *   buf      Data to send
  *   len      Length of data to send
+ *   flags    Send flags
  *
  * Returned Value:
  *   On success, returns the number of characters sent.  On  error,
@@ -931,11 +932,12 @@ static inline void send_txnotify(FAR struct socket *psock,
  ****************************************************************************/
 
 ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
-                       size_t len)
+                       size_t len, int flags)
 {
   FAR struct tcp_conn_s *conn;
   FAR struct tcp_wrbuffer_s *wrb;
   ssize_t    result = 0;
+  bool       nonblock;
   int        ret = OK;
 
   if (psock == NULL || psock->s_crefs <= 0)
@@ -990,6 +992,8 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
     }
 #endif /* CONFIG_NET_ARP_SEND || CONFIG_NET_ICMPv6_NEIGHBOR */
 
+  nonblock = _SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0;
+
   /* Dump the incoming buffer */
 
   BUF_DUMP("psock_tcp_send", buf, len);
@@ -1001,7 +1005,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
        */
 
       net_lock();
-      if (_SS_ISNONBLOCK(psock->s_flags))
+      if (nonblock)
         {
           wrb = tcp_wrbuffer_tryalloc();
         }
@@ -1015,7 +1019,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
           /* A buffer allocation error occurred */
 
           nerr("ERROR: Failed to allocate write buffer\n");
-          ret = _SS_ISNONBLOCK(psock->s_flags) ? -EAGAIN : -ENOMEM;
+          ret = nonblock ? -EAGAIN : -ENOMEM;
           goto errout_with_lock;
         }
 
@@ -1033,7 +1037,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
           /* A buffer allocation error occurred */
 
           nerr("ERROR: Failed to allocate callback\n");
-          ret = _SS_ISNONBLOCK(psock->s_flags) ? -EAGAIN : -ENOMEM;
+          ret = nonblock ? -EAGAIN : -ENOMEM;
           goto errout_with_wrb;
         }
 
@@ -1053,7 +1057,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf,
        * buffer space if the socket was opened non-blocking.
        */
 
-      if (_SS_ISNONBLOCK(psock->s_flags))
+      if (nonblock)
         {
           /* The return value from TCP_WBTRYCOPYIN is either OK or
            * -ENOMEM if less than the entire data chunk could be allocated.
diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c
index 1ff0406..189afb1 100644
--- a/net/tcp/tcp_send_unbuffered.c
+++ b/net/tcp/tcp_send_unbuffered.c
@@ -537,6 +537,7 @@ static inline void send_txnotify(FAR struct socket *psock,
  *   psock    An instance of the internal socket structure.
  *   buf      Data to send
  *   len      Length of data to send
+ *   flags    Send flags
  *
  * Returned Value:
  *   On success, returns the number of characters sent.  On  error,
@@ -582,7 +583,7 @@ static inline void send_txnotify(FAR struct socket *psock,
  ****************************************************************************/
 
 ssize_t psock_tcp_send(FAR struct socket *psock,
-                       FAR const void *buf, size_t len)
+                       FAR const void *buf, size_t len, int flags)
 {
   FAR struct tcp_conn_s *conn;
   struct send_s state;
diff --git a/net/udp/udp.h b/net/udp/udp.h
index 454b29f..165d0c1 100644
--- a/net/udp/udp.h
+++ b/net/udp/udp.h
@@ -644,10 +644,12 @@ uint16_t udp_callback(FAR struct net_driver_s *dev,
  *   Perform the recvfrom operation for a UDP SOCK_DGRAM
  *
  * Input Parameters:
- *   psock  Pointer to the socket structure for the SOCK_DRAM socket
- *   buf    Buffer to receive data
- *   len    Length of buffer
- *   from   INET address of source (may be NULL)
+ *   psock    Pointer to the socket structure for the SOCK_DRAM socket
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   flags    Receive flags
+ *   from     INET address of source (may be NULL)
+ *   fromlen  The length of the address structure
  *
  * Returned Value:
  *   On success, returns the number of characters received.  On  error,
@@ -658,7 +660,7 @@ uint16_t udp_callback(FAR struct net_driver_s *dev,
  ****************************************************************************/
 
 ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR void *buf,
-                           size_t len, FAR struct sockaddr *from,
+                           size_t len, int flags, FAR struct sockaddr *from,
                            FAR socklen_t *fromlen);
 
 /****************************************************************************
diff --git a/net/udp/udp_recvfrom.c b/net/udp/udp_recvfrom.c
index 7a320a7..3250435 100644
--- a/net/udp/udp_recvfrom.c
+++ b/net/udp/udp_recvfrom.c
@@ -606,7 +606,7 @@ static ssize_t udp_recvfrom_result(int result, struct udp_recvfrom_s *pstate)
  ****************************************************************************/
 
 ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR void *buf,
-                           size_t len, FAR struct sockaddr *from,
+                           size_t len, int flags, FAR struct sockaddr *from,
                            FAR socklen_t *fromlen)
 {
   FAR struct udp_conn_s *conn = (FAR struct udp_conn_s *)psock->s_conn;
@@ -637,7 +637,7 @@ ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR void *buf,
 
   /* Handle non-blocking UDP sockets */
 
-  if (_SS_ISNONBLOCK(psock->s_flags))
+  if (_SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0)
     {
       /* Return the number of bytes read from the read-ahead buffer if
        * something was received (already in 'ret'); EAGAIN if not.
diff --git a/net/udp/udp_sendto_buffered.c b/net/udp/udp_sendto_buffered.c
index 8428482..231728d 100644
--- a/net/udp/udp_sendto_buffered.c
+++ b/net/udp/udp_sendto_buffered.c
@@ -504,6 +504,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
 {
   FAR struct udp_conn_s *conn;
   FAR struct udp_wrbuffer_s *wrb;
+  bool nonblock;
   bool empty;
   int ret = OK;
 
@@ -628,6 +629,8 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
     }
 #endif /* CONFIG_NET_ARP_SEND || CONFIG_NET_ICMPv6_NEIGHBOR */
 
+  nonblock = _SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0;
+
   /* Dump the incoming buffer */
 
   BUF_DUMP("psock_udp_sendto", buf, len);
@@ -640,7 +643,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
        * unlocked here.
        */
 
-      if (_SS_ISNONBLOCK(psock->s_flags))
+      if (nonblock)
         {
           wrb = udp_wrbuffer_tryalloc();
         }
@@ -654,7 +657,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
           /* A buffer allocation error occurred */
 
           nerr("ERROR: Failed to allocate write buffer\n");
-          ret = _SS_ISNONBLOCK(psock->s_flags) ? -EAGAIN : -ENOMEM;
+          ret = nonblock ? -EAGAIN : -ENOMEM;
           goto errout_with_lock;
         }
 
@@ -707,7 +710,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
        * buffer space if the socket was opened non-blocking.
        */
 
-      if (_SS_ISNONBLOCK(psock->s_flags))
+      if (nonblock)
         {
           ret = iob_trycopyin(wrb->wb_iob, (FAR uint8_t *)buf, len, 0, false,
                               IOBUSER_NET_SOCK_UDP);
diff --git a/net/usrsock/usrsock_recvfrom.c b/net/usrsock/usrsock_recvfrom.c
index 2f12f10..8f7d51e 100644
--- a/net/usrsock/usrsock_recvfrom.c
+++ b/net/usrsock/usrsock_recvfrom.c
@@ -308,7 +308,7 @@ ssize_t usrsock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
 
       if (!(conn->flags & USRSOCK_EVENT_RECVFROM_AVAIL))
         {
-          if (_SS_ISNONBLOCK(psock->s_flags))
+          if (_SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0)
             {
               /* Nothing to receive from daemon side. */
 
diff --git a/net/usrsock/usrsock_sendto.c b/net/usrsock/usrsock_sendto.c
index ed302a8..16d3708 100644
--- a/net/usrsock/usrsock_sendto.c
+++ b/net/usrsock/usrsock_sendto.c
@@ -294,7 +294,7 @@ ssize_t usrsock_sendto(FAR struct socket *psock, FAR const void *buf,
 
       if (!(conn->flags & USRSOCK_EVENT_SENDTO_READY))
         {
-          if (_SS_ISNONBLOCK(psock->s_flags))
+          if (_SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0)
             {
               /* Send busy at daemon side. */