ccollins476ad closed pull request #938: native_sockets - handle non-blocking 
connects.
URL: https://github.com/apache/mynewt-core/pull/938
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/net/ip/mn_socket/test/src/mn_sock_test.c 
b/net/ip/mn_socket/test/src/mn_sock_test.c
index 0d7885bf8..725e8a7d1 100644
--- a/net/ip/mn_socket/test/src/mn_sock_test.c
+++ b/net/ip/mn_socket/test/src/mn_sock_test.c
@@ -85,6 +85,6 @@ main(int argc, char **argv)
     tu_suite_set_init_cb((void*)mn_socket_test_init, NULL);
     mn_socket_test_all();
 
-    return 0;
+    return tu_any_failed;
 }
 #endif
diff --git a/net/ip/mn_socket/test/src/mn_sock_util.c 
b/net/ip/mn_socket/test/src/mn_sock_util.c
index 3c9e0396f..25ead97ac 100644
--- a/net/ip/mn_socket/test/src/mn_sock_util.c
+++ b/net/ip/mn_socket/test/src/mn_sock_util.c
@@ -89,6 +89,14 @@ stc_writable(void *cb_arg, int err)
     TEST_ASSERT(err == 0);
     i = (int *)cb_arg;
     *i = *i + 1;
+
+    /*
+     * The first instance of writability indicates an established connection.
+     * Unblock the test case.
+     */
+    if (*i == 1) {
+        os_sem_release(&test_sem);
+    }
 }
 
 int
@@ -144,8 +152,14 @@ sock_tcp_connect(void)
     rc = mn_connect(sock, (struct mn_sockaddr *)&msin);
     TEST_ASSERT(rc == 0);
 
+    /*
+     * Wait for both connections to be established.
+     */
+    rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC);
+    TEST_ASSERT(rc == 0);
     rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC);
     TEST_ASSERT(rc == 0);
+
     TEST_ASSERT(connected == 1);
     TEST_ASSERT(new_sock != NULL);
 
@@ -271,9 +285,18 @@ std_writable(void *cb_arg, int err)
     int *i;
 
     TEST_ASSERT(err == 0);
+
     i = (int *)cb_arg;
-    if (i) {
-        *i = *i + 1;
+    TEST_ASSERT_FATAL(i != NULL);
+
+    *i = *i + 1;
+
+    /*
+     * The first instance of writability indicates an established connection.
+     * Unblock the test case.
+     */
+    if (*i == 1) {
+        os_sem_release(&test_sem);
     }
 }
 
@@ -341,8 +364,14 @@ sock_tcp_data(void)
     rc = mn_connect(sock, (struct mn_sockaddr *)&msin);
     TEST_ASSERT(rc == 0);
 
+    /*
+     * Wait for both connections to be established.
+     */
     rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC);
     TEST_ASSERT(rc == 0);
+    rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC);
+    TEST_ASSERT(rc == 0);
+
     TEST_ASSERT(connected == 1);
     TEST_ASSERT(new_sock != NULL);
 
diff --git a/net/ip/native_sockets/src/native_sock.c 
b/net/ip/native_sockets/src/native_sock.c
index 17c391d85..f8e2a936c 100644
--- a/net/ip/native_sockets/src/native_sock.c
+++ b/net/ip/native_sockets/src/native_sock.c
@@ -58,6 +58,7 @@ static int native_sock_getpeername(struct mn_socket *, struct 
mn_sockaddr *);
 static struct native_sock {
     struct mn_socket ns_sock;
     int ns_fd;
+    unsigned int ns_connect:1;  /* Non-blocking connect in progress. */
     unsigned int ns_poll:1;
     unsigned int ns_listen:1;
     uint8_t ns_type;
@@ -360,21 +361,34 @@ native_sock_connect(struct mn_socket *s, struct 
mn_sockaddr *addr)
     struct sockaddr *sa = (struct sockaddr *)&ss;
     int rc;
     int sa_len;
+    int in_progress = 0;
 
     rc = native_sock_mn_addr_to_addr(addr, sa, &sa_len);
     if (rc) {
         return rc;
     }
     os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
-    if (connect(ns->ns_fd, sa, sa_len)) {
-        rc = errno;
-        os_mutex_release(&nss->mtx);
-        return native_sock_err_to_mn_err(rc);
+    rc = connect(ns->ns_fd, sa, sa_len);
+    if (rc != 0) {
+        if (errno == EINPROGRESS) {
+            /* Non-blocking connect initiated. */
+            in_progress = 1;
+            ns->ns_connect = 1;
+        } else {
+            rc = errno;
+            os_mutex_release(&nss->mtx);
+            return native_sock_err_to_mn_err(rc);
+        }
     }
     ns->ns_poll = 1;
     native_sock_poll_rebuild(nss);
     os_mutex_release(&nss->mtx);
-    mn_socket_writable(s, 0);
+
+    /* Indicate writability if connection fully established. */
+    if (!in_progress) {
+        mn_socket_writable(s, 0);
+    }
+
     return 0;
 }
 
@@ -742,6 +756,7 @@ socket_task(void *arg)
     int revents;
     int i;
     socklen_t slen;
+    int sock_err;
     int rc;
 
     os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
@@ -796,7 +811,23 @@ socket_task(void *arg)
             }
 
             if (revents & POLLOUT) {
-                if (ns->ns_type == SOCK_STREAM && ns->ns_tx) {
+                if (ns->ns_connect) {
+                    /*
+                     * The connection attempt has completed.  Report whether it
+                     * succeeded.
+                     */
+                    ns->ns_connect = 0;
+
+                    slen = sizeof(sock_err);
+                    rc = getsockopt(ns->ns_fd, SOL_SOCKET, SO_ERROR,
+                                    &sock_err, &slen);
+                    if (rc != 0) {
+                        rc = native_sock_err_to_mn_err(errno);
+                    } else if (sock_err != 0) {
+                        rc = native_sock_err_to_mn_err(sock_err);
+                    }
+                    mn_socket_writable(&ns->ns_sock, rc);
+                } else if (ns->ns_type == SOCK_STREAM && ns->ns_tx) {
                     native_sock_stream_tx(ns, 1);
                 }
             }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to