Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 2 Jun 2013 08:52:48 +0000 (10:52 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 2 Jun 2013 09:02:02 +0000 (11:02 +0200)
* qatar/master:
  network: factor out connect-listening code

Conflicts:
libavformat/network.h
libavformat/tcp.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/network.c
libavformat/network.h
libavformat/tcp.c

   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
 +#include "libavutil/avutil.h"
  #include "network.h"
+ #include "url.h"
  #include "libavcodec/internal.h"
  #include "libavutil/mem.h"
 +#include "url.h"
 +#include "libavutil/time.h"
  
  #if HAVE_THREADS
  #if HAVE_PTHREADS
@@@ -241,3 -217,48 +242,50 @@@ int ff_listen_bind(int fd, const struc
      ff_socket_nonblock(ret, 1);
      return ret;
  }
 -                      socklen_t addrlen, int timeout, URLContext *h)
+ int ff_listen_connect(int fd, const struct sockaddr *addr,
 -            while (timeout--) {
++                      socklen_t addrlen, int rw_timeout, URLContext *h)
+ {
+     struct pollfd p = {fd, POLLOUT, 0};
++    int64_t wait_started;
+     int ret;
+     socklen_t optlen;
+     ff_socket_nonblock(fd, 1);
+     while ((ret = connect(fd, addr, addrlen))) {
+         ret = ff_neterrno();
+         switch (ret) {
+         case AVERROR(EINTR):
+             if (ff_check_interrupt(&h->interrupt_callback))
+                 return AVERROR_EXIT;
+             continue;
+         case AVERROR(EINPROGRESS):
+         case AVERROR(EAGAIN):
 -            }
++            wait_started = av_gettime();
++            do {
+                 if (ff_check_interrupt(&h->interrupt_callback))
+                     return AVERROR_EXIT;
+                 ret = poll(&p, 1, 100);
+                 if (ret > 0)
+                     break;
++            } while (!rw_timeout || (av_gettime() - wait_started < rw_timeout));
+             if (ret <= 0)
+                 return AVERROR(ETIMEDOUT);
+             optlen = sizeof(ret);
+             if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
+                 ret = AVUNERROR(ff_neterrno());
+             if (ret != 0) {
+                 char errbuf[100];
+                 ret = AVERROR(ret);
+                 av_strerror(ret, errbuf, sizeof(errbuf));
+                 av_log(h, AV_LOG_ERROR,
+                        "Connection to %s failed: %s\n",
+                        h->filename, errbuf);
+             }
+         default:
+             return ret;
+         }
+     }
+     return ret;
+ }
@@@ -27,7 -27,7 +27,8 @@@
  #include "config.h"
  #include "libavutil/error.h"
  #include "os_support.h"
 +#include "avio.h"
+ #include "url.h"
  
  #if HAVE_UNISTD_H
  #include <unistd.h>
@@@ -64,10 -41,10 +64,9 @@@ static int tcp_open(URLContext *h, cons
      const char *p;
      char buf[256];
      int ret;
-     socklen_t optlen;
 -    int timeout = 100, listen_timeout = -1;
      char hostname[1024],proto[1024],path[1024];
      char portstr[10];
 +    h->rw_timeout = 5000000;
  
      av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
          &port, path, sizeof(path), uri);
              goto fail1;
          }
      } else {
-  redo:
-         ff_socket_nonblock(fd, 1);
-         ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
-     }
+         if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
 -                                     timeout, h)) < 0) {
++                                     h->rw_timeout, h)) < 0) {
  
-     if (ret < 0) {
-         struct pollfd p = {fd, POLLOUT, 0};
-         int64_t wait_started;
-         ret = ff_neterrno();
-         if (ret == AVERROR(EINTR)) {
-             if (ff_check_interrupt(&h->interrupt_callback)) {
-                 ret = AVERROR_EXIT;
+             if (ret == AVERROR_EXIT)
                  goto fail1;
-             }
-             goto redo;
-         }
-         if (ret != AVERROR(EINPROGRESS) &&
-             ret != AVERROR(EAGAIN))
-             goto fail;
-         /* wait until we are connected or until abort */
-         wait_started = av_gettime();
-         do {
-             if (ff_check_interrupt(&h->interrupt_callback)) {
-                 ret = AVERROR_EXIT;
-                 goto fail1;
-             }
-             ret = poll(&p, 1, 100);
-             if (ret > 0)
-                 break;
-         } while (!h->rw_timeout || (av_gettime() - wait_started < h->rw_timeout));
-         if (ret <= 0) {
-             ret = AVERROR(ETIMEDOUT);
-             goto fail;
-         }
-         /* test error */
-         optlen = sizeof(ret);
-         if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
-             ret = AVUNERROR(ff_neterrno());
-         if (ret != 0) {
-             char errbuf[100];
-             ret = AVERROR(ret);
-             av_strerror(ret, errbuf, sizeof(errbuf));
-             av_log(h, AV_LOG_ERROR,
-                    "TCP connection to %s:%d failed: %s\n",
-                    hostname, port, errbuf);
-             goto fail;
+             else
+                 goto fail;
          }
      }
      h->is_streamed = 1;
      s->fd = fd;
      freeaddrinfo(ai);