diff options
Diffstat (limited to 'libavformat/network.c')
-rw-r--r-- | libavformat/network.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/libavformat/network.c b/libavformat/network.c index 6f43c41626..f80f43ec2a 100644 --- a/libavformat/network.c +++ b/libavformat/network.c @@ -18,14 +18,19 @@ * 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 #include <pthread.h> +#elif HAVE_OS2THREADS +#include "compat/os2threads.h" #else #include "compat/w32pthreads.h" #endif @@ -146,6 +151,26 @@ int ff_network_wait_fd(int fd, int write) return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN); } +int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb) +{ + int ret; + int64_t wait_start = 0; + + while (1) { + ret = ff_network_wait_fd(fd, write); + if (ret != AVERROR(EAGAIN)) + return ret; + if (ff_check_interrupt(int_cb)) + return AVERROR_EXIT; + if (timeout) { + if (!wait_start) + wait_start = av_gettime(); + else if (av_gettime() - wait_start > timeout) + return AVERROR(ETIMEDOUT); + } + } +} + void ff_network_close(void) { #if HAVE_WINSOCK2_H @@ -219,9 +244,10 @@ int ff_listen_bind(int fd, const struct sockaddr *addr, } int ff_listen_connect(int fd, const struct sockaddr *addr, - socklen_t addrlen, int timeout, URLContext *h) + socklen_t addrlen, int rw_timeout, URLContext *h) { struct pollfd p = {fd, POLLOUT, 0}; + int64_t wait_started; int ret; socklen_t optlen; @@ -236,13 +262,14 @@ int ff_listen_connect(int fd, const struct sockaddr *addr, continue; case AVERROR(EINPROGRESS): case AVERROR(EAGAIN): - while (timeout--) { + 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); |