From ebba2b3e2a551ce638d17332761431ba748f178f Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 4 Apr 2011 18:17:12 +0200 Subject: [PATCH] proto: factor ff_network_wait_fd and use it on udp Support the URL_FLAG_NONBLOCK semantic and uniform the protocol. The quick retry loop is already part of retry_transfer_wrapper. The polling routine is common to the network protocols: udp, tcp and, once merged, sctp. --- libavformat/network.h | 13 ++++++++++ libavformat/tcp.c | 14 ++-------- libavformat/udp.c | 59 ++++++++++++++----------------------------- 3 files changed, 34 insertions(+), 52 deletions(-) diff --git a/libavformat/network.h b/libavformat/network.h index 27bebb3505..6943bc6765 100644 --- a/libavformat/network.h +++ b/libavformat/network.h @@ -55,6 +55,10 @@ static inline int ff_neterrno() { #include #endif +#if HAVE_POLL_H +#include +#endif + int ff_socket_nonblock(int socket, int enable); static inline int ff_network_init(void) @@ -67,6 +71,15 @@ static inline int ff_network_init(void) return 1; } +static inline int ff_network_wait_fd(int fd, int write) +{ + int ev = write ? POLLOUT : POLLIN; + struct pollfd p = { .fd = fd, .events = ev, .revents = 0 }; + int ret; + ret = poll(&p, 1, 100); + return ret < 0 ? ff_neterrno() : p.revents & ev ? 0 : AVERROR(EAGAIN); +} + static inline void ff_network_close(void) { #if HAVE_WINSOCK2_H diff --git a/libavformat/tcp.c b/libavformat/tcp.c index 37e6d6f10e..cf294dc4b9 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -131,23 +131,13 @@ static int tcp_open(URLContext *h, const char *uri, int flags) return ret; } -static int tcp_wait_fd(int fd, int write) -{ - int ev = write ? POLLOUT : POLLIN; - struct pollfd p = { .fd = fd, .events = ev, .revents = 0 }; - int ret; - - ret = poll(&p, 1, 100); - return ret < 0 ? ff_neterrno() : p.revents & ev ? 0 : AVERROR(EAGAIN); -} - static int tcp_read(URLContext *h, uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret; if (!(h->flags & URL_FLAG_NONBLOCK)) { - ret = tcp_wait_fd(s->fd, 0); + ret = ff_network_wait_fd(s->fd, 0); if (ret < 0) return ret; } @@ -161,7 +151,7 @@ static int tcp_write(URLContext *h, const uint8_t *buf, int size) int ret; if (!(h->flags & URL_FLAG_NONBLOCK)) { - ret = tcp_wait_fd(s->fd, 1); + ret = ff_network_wait_fd(s->fd, 1); if (ret < 0) return ret; } diff --git a/libavformat/udp.c b/libavformat/udp.c index 8d50218f19..72e2ab53d0 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -33,9 +33,6 @@ #include "internal.h" #include "network.h" #include "os_support.h" -#if HAVE_POLL_H -#include -#endif #include #ifndef IPV6_ADD_MEMBERSHIP @@ -447,31 +444,15 @@ static int udp_open(URLContext *h, const char *uri, int flags) static int udp_read(URLContext *h, uint8_t *buf, int size) { UDPContext *s = h->priv_data; - struct pollfd p = {s->udp_fd, POLLIN, 0}; - int len; int ret; - for(;;) { - if (url_interrupt_cb()) - return AVERROR_EXIT; - ret = poll(&p, 1, 100); - if (ret < 0) { - if (ff_neterrno() == AVERROR(EINTR)) - continue; - return AVERROR(EIO); - } - if (!(ret == 1 && p.revents & POLLIN)) - continue; - len = recv(s->udp_fd, buf, size, 0); - if (len < 0) { - if (ff_neterrno() != AVERROR(EAGAIN) && - ff_neterrno() != AVERROR(EINTR)) - return AVERROR(EIO); - } else { - break; - } + if (!(h->flags & URL_FLAG_NONBLOCK)) { + ret = ff_network_wait_fd(s->udp_fd, 0); + if (ret < 0) + return ret; } - return len; + ret = recv(s->udp_fd, buf, size, 0); + return ret < 0 ? ff_neterrno() : ret; } static int udp_write(URLContext *h, const uint8_t *buf, int size) @@ -479,22 +460,20 @@ static int udp_write(URLContext *h, const uint8_t *buf, int size) UDPContext *s = h->priv_data; int ret; - for(;;) { - if (!s->is_connected) { - ret = sendto (s->udp_fd, buf, size, 0, - (struct sockaddr *) &s->dest_addr, - s->dest_addr_len); - } else - ret = send(s->udp_fd, buf, size, 0); - if (ret < 0) { - if (ff_neterrno() != AVERROR(EINTR) && - ff_neterrno() != AVERROR(EAGAIN)) - return ff_neterrno(); - } else { - break; - } + if (!(h->flags & URL_FLAG_NONBLOCK)) { + ret = ff_network_wait_fd(s->udp_fd, 1); + if (ret < 0) + return ret; } - return size; + + if (!s->is_connected) { + ret = sendto (s->udp_fd, buf, size, 0, + (struct sockaddr *) &s->dest_addr, + s->dest_addr_len); + } else + ret = send(s->udp_fd, buf, size, 0); + + return ret < 0 ? ff_neterrno() : ret; } static int udp_close(URLContext *h) -- GitLab