int reconnect;
int reconnect_at_eof;
int reconnect_streamed;
- int reconnect_delay;
int reconnect_delay_max;
int listen;
char *resource;
HTTPContext *s = h->priv_data;
int err, new_location, read_ret;
int64_t seek_ret;
+ int reconnect_delay = 0;
if (!s->hd)
return AVERROR_EOF;
return http_buf_read_compressed(h, buf, size);
#endif /* CONFIG_ZLIB */
read_ret = http_buf_read(h, buf, size);
- if ( (read_ret < 0 && s->reconnect && (!h->is_streamed || s->reconnect_streamed) && s->filesize > 0 && s->off < s->filesize)
- || (read_ret == 0 && s->reconnect_at_eof && (!h->is_streamed || s->reconnect_streamed))) {
+ while ((read_ret < 0 && s->reconnect && (!h->is_streamed || s->reconnect_streamed) && s->filesize > 0 && s->off < s->filesize)
+ || (read_ret == AVERROR_EOF && s->reconnect_at_eof && (!h->is_streamed || s->reconnect_streamed))) {
uint64_t target = h->is_streamed ? 0 : s->off;
- if (s->reconnect_delay > s->reconnect_delay_max)
+ if (reconnect_delay > s->reconnect_delay_max)
return AVERROR(EIO);
av_log(h, AV_LOG_INFO, "Will reconnect at %"PRIu64" error=%s.\n", s->off, av_err2str(read_ret));
- av_usleep(1000U*1000*s->reconnect_delay);
- s->reconnect_delay = 1 + 2*s->reconnect_delay;
+ err = ff_network_sleep_interruptible(1000U*1000*reconnect_delay, &h->interrupt_callback);
+ if (err != AVERROR(ETIMEDOUT))
+ return err;
+ reconnect_delay = 1 + 2*reconnect_delay;
seek_ret = http_seek_internal(h, target, SEEK_SET, 1);
- if (seek_ret != target) {
+ if (seek_ret >= 0 && seek_ret != target) {
av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", target);
return read_ret;
}
read_ret = http_buf_read(h, buf, size);
- } else
- s->reconnect_delay = 0;
+ }
return read_ret;
}
}
}
+int ff_network_sleep_interruptible(int64_t timeout, AVIOInterruptCB *int_cb)
+{
+ int64_t wait_start = av_gettime_relative();
+
+ while (1) {
+ int64_t time_left;
+
+ if (ff_check_interrupt(int_cb))
+ return AVERROR_EXIT;
+
+ time_left = timeout - (av_gettime_relative() - wait_start);
+ if (time_left <= 0)
+ return AVERROR(ETIMEDOUT);
+
+ av_usleep(FFMIN(time_left, POLLING_TIME * 1000));
+ }
+}
+
void ff_network_close(void)
{
#if HAVE_WINSOCK2_H
*/
int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb);
+/**
+ * Waits for up to 'timeout' microseconds. If the usert's int_cb is set and
+ * triggered, return before that.
+ * @timeout Timeout in microseconds. Maybe have lower actual precision.
+ * @param int_cb Interrupt callback, is checked regularly.
+ * @return AVERROR(ETIMEDOUT) if timeout expirted, AVERROR_EXIT if interrupted by int_cb
+ */
+int ff_network_sleep_interruptible(int64_t timeout, AVIOInterruptCB *int_cb);
+
int ff_inet_aton (const char * str, struct in_addr * add);
#if !HAVE_STRUCT_SOCKADDR_STORAGE