summaryrefslogtreecommitdiff
path: root/libavformat/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/network.c')
-rw-r--r--libavformat/network.c33
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);