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

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new b8a9ddd  oic tcp4_adaptor: Don't loop if nothing to rx
b8a9ddd is described below

commit b8a9ddd8a07fda008c2083de026fe0549f16046a
Author: Christopher Collins <ccoll...@apache.org>
AuthorDate: Wed May 27 17:35:10 2020 -0700

    oic tcp4_adaptor: Don't loop if nothing to rx
    
    Prior to commit:
    
    When a managed TCP connection had no pending receives, the code would
    enqueue another "rx" event.  As a result, the "rx" event would always be
    executing or enqueued!
    
    Fix:
    
    If a connection has no pending receives, move on to the next connection.
    Do not enqueue an "rx" event.
---
 net/oic/src/port/mynewt/tcp4_adaptor.c | 52 +++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 14 deletions(-)

diff --git a/net/oic/src/port/mynewt/tcp4_adaptor.c 
b/net/oic/src/port/mynewt/tcp4_adaptor.c
index 9d132a6..deea866 100644
--- a/net/oic/src/port/mynewt/tcp4_adaptor.c
+++ b/net/oic/src/port/mynewt/tcp4_adaptor.c
@@ -294,27 +294,51 @@ oc_connectivity_shutdown_tcp4(void)
     }
 }
 
-static void
-oc_event_tcp4(struct os_event *ev)
+/**
+ * Receives all buffered packets sent over the given connection.
+ */
+static int
+oc_tcp4_recv_conn(struct oc_tcp4_conn *conn)
 {
     struct mn_sockaddr_in from;
-    struct oc_tcp4_conn *conn;
     struct os_mbuf *frag;
     int rc;
 
-    SLIST_FOREACH(conn, &oc_tcp4_conn_list, next) {
-        while (1) {
-            rc = mn_recvfrom(conn->sock, &frag, (struct mn_sockaddr *) &from);
-            if (rc != 0) {
-                if (rc != MN_EAGAIN) {
-                    oc_tcp4_err(conn->sock, rc);
-                }
-                os_eventq_put(oc_evq_get(), &oc_tcp4_read_event);
-                return;
-            }
-
+    /* Keep receiving until there are no more pending packets. */
+    while (1) {
+        rc = mn_recvfrom(conn->sock, &frag, (struct mn_sockaddr *) &from);
+        switch (rc) {
+        case 0:
             assert(OS_MBUF_IS_PKTHDR(frag));
             oc_tcp_rx_frag(conn->sock, frag, &from);
+            break;
+
+        case MN_EAGAIN:
+            // No more packets to receive.
+            return 0;
+
+        default:
+            return rc;
+        }
+    }
+}
+
+static void
+oc_event_tcp4(struct os_event *ev)
+{
+    struct oc_tcp4_conn *conn;
+    int rc;
+
+    SLIST_FOREACH(conn, &oc_tcp4_conn_list, next) {
+        rc = oc_tcp4_recv_conn(conn);
+        if (rc != 0) {
+            /* The connection is in a bad state and needs to be removed from
+             * the list.  We can't continue looping after modifying the list,
+             * so enqueue "receive" event and return.
+             */
+            oc_tcp4_err(conn->sock, rc);
+            os_eventq_put(oc_evq_get(), &oc_tcp4_read_event);
+            return;
         }
     }
 }

Reply via email to