]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
tcp: rewrite connection timeout using tvhpoll wrapper
authorJaroslav Kysela <perex@perex.cz>
Sun, 1 Jun 2014 20:23:37 +0000 (22:23 +0200)
committerJaroslav Kysela <perex@perex.cz>
Sun, 1 Jun 2014 20:33:56 +0000 (22:33 +0200)
src/tcp.c

index eacaed670bce79080d7224b82e36c07b3a45943b..f2c5e6e49aa1375a0f9f714a7bb9af0acbc25c3e 100644 (file)
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -99,29 +99,45 @@ tcp_connect(const char *hostname, int port, const char *bindaddr,
   freeaddrinfo(ai);
 
   if(r == -1) {
+    /* timeout < 0 - do not wait at all */
     if(errno == EINPROGRESS && timeout < 0) {
       err = 0;
     } else if(errno == EINPROGRESS) {
-      struct pollfd pfd;
-
-      pfd.fd = fd;
-      pfd.events = POLLOUT;
-      pfd.revents = 0;
-
-      r = poll(&pfd, 1, timeout * 1000);
-      if(r == 0) {
-             /* Timeout */
-       snprintf(errbuf, errbufsize, "Connection attempt timed out");
-       close(fd);
-       return -1;
-      }
+      tvhpoll_event_t ev;
+      tvhpoll_t *efd;
+
+      efd = tvhpoll_create(1);
+      memset(&ev, 0, sizeof(ev));
+      ev.events   = TVHPOLL_OUT;
+      ev.fd       = fd;
+      ev.data.ptr = &fd;
+      tvhpoll_add(efd, &ev, 1);
+
+      /* minimal timeout is one second */
+      if (timeout < 1)
+        timeout = 0;
+
+      while (1) {
+        r = tvhpoll_wait(efd, &ev, 1, timeout * 1000);
+        if (r > 0)
+          break;
+        
+        if (r == 0) { /* Timeout */
+          snprintf(errbuf, errbufsize, "Connection attempt timed out");
+          tvhpoll_destroy(efd);
+          close(fd);
+          return -1;
+        }
       
-      if(r == -1) {
-       snprintf(errbuf, errbufsize, "poll() error: %s", strerror(errno));
-       close(fd);
-       return -1;
+        if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) {
+          snprintf(errbuf, errbufsize, "poll() error: %s", strerror(errno));
+          tvhpoll_destroy(efd);
+          close(fd);
+          return -1;
+        }
       }
-
+      
+      tvhpoll_destroy(efd);
       getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen);
     } else {
       err = errno;