os: replace select with poll

Select has limitations on the fd values it could accept and silently
breaks when it is reached.
(cherry picked from commit a8475bbdb6)
oldabi
Luca Barbato 14 years ago committed by Michael Niedermayer
parent b5f83debf5
commit d0eb91ad04
  1. 3
      libavformat/os_support.c
  2. 24
      libavformat/rtpproto.c
  3. 55
      libavformat/rtsp.c
  4. 5
      libavformat/rtsp.h
  5. 19
      libavformat/rtspenc.c
  6. 14
      libavformat/sapdec.c
  7. 48
      libavformat/tcp.c
  8. 15
      libavformat/udp.c

@ -236,7 +236,6 @@ int ff_socket_nonblock(int socket, int enable)
}
#endif /* CONFIG_NETWORK */
#if CONFIG_FFSERVER
#if !HAVE_POLL_H
int poll(struct pollfd *fds, nfds_t numfds, int timeout)
{
@ -305,5 +304,3 @@ int poll(struct pollfd *fds, nfds_t numfds, int timeout)
return rc;
}
#endif /* HAVE_POLL_H */
#endif /* CONFIG_FFSERVER */

@ -34,8 +34,8 @@
#include "network.h"
#include "os_support.h"
#include <fcntl.h>
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#if HAVE_POLL_H
#include <sys/poll.h>
#endif
#include <sys/time.h>
@ -221,9 +221,9 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
RTPContext *s = h->priv_data;
struct sockaddr_storage from;
socklen_t from_len;
int len, fd_max, n;
fd_set rfds;
struct timeval tv;
int len, n;
struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};
#if 0
for(;;) {
from_len = sizeof(from);
@ -242,18 +242,10 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
if (url_interrupt_cb())
return AVERROR(EINTR);
/* build fdset to listen to RTP and RTCP packets */
FD_ZERO(&rfds);
fd_max = s->rtp_fd;
FD_SET(s->rtp_fd, &rfds);
if (s->rtcp_fd > fd_max)
fd_max = s->rtcp_fd;
FD_SET(s->rtcp_fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
n = poll(p, 2, 100);
if (n > 0) {
/* first try RTCP */
if (FD_ISSET(s->rtcp_fd, &rfds)) {
if (p[1].revents & POLLIN) {
from_len = sizeof(from);
len = recvfrom (s->rtcp_fd, buf, size, 0,
(struct sockaddr *)&from, &from_len);
@ -266,7 +258,7 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
break;
}
/* then RTP */
if (FD_ISSET(s->rtp_fd, &rfds)) {
if (p[0].revents & POLLIN) {
from_len = sizeof(from);
len = recvfrom (s->rtp_fd, buf, size, 0,
(struct sockaddr *)&from, &from_len);

@ -26,8 +26,8 @@
#include "avformat.h"
#include <sys/time.h>
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#if HAVE_POLL_H
#include <poll.h>
#endif
#include <strings.h>
#include "internal.h"
@ -44,11 +44,11 @@
//#define DEBUG
//#define DEBUG_RTP_TCP
/* Timeout values for socket select, in ms,
/* Timeout values for socket poll, in ms,
* and read_packet(), in seconds */
#define SELECT_TIMEOUT_MS 100
#define POLL_TIMEOUT_MS 100
#define READ_PACKET_TIMEOUT_S 10
#define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / SELECT_TIMEOUT_MS
#define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / POLL_TIMEOUT_MS
#define SDP_MAX_SIZE 16384
#define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
@ -429,8 +429,14 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
}
}
/**
* Parse the sdp description and allocate the rtp streams and the
* pollfd array used for udp ones.
*/
int ff_sdp_parse(AVFormatContext *s, const char *content)
{
RTSPState *rt = s->priv_data;
const char *p;
int letter;
/* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
@ -470,6 +476,8 @@ int ff_sdp_parse(AVFormatContext *s, const char *content)
if (*p == '\n')
p++;
}
rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1));
if (!rt->p) return AVERROR(ENOMEM);
return 0;
}
#endif /* CONFIG_RTPDEC */
@ -531,6 +539,7 @@ void ff_rtsp_close_streams(AVFormatContext *s)
av_close_input_stream (rt->asf_ctx);
rt->asf_ctx = NULL;
}
av_free(rt->p);
av_free(rt->recvbuf);
}
@ -1554,55 +1563,51 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
{
RTSPState *rt = s->priv_data;
RTSPStream *rtsp_st;
fd_set rfds;
int fd, fd_rtcp, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0;
struct timeval tv;
int n, i, ret, tcp_fd, timeout_cnt = 0;
int max_p = 0;
struct pollfd *p = rt->p;
for (;;) {
if (url_interrupt_cb())
return AVERROR(EINTR);
if (wait_end && wait_end - av_gettime() < 0)
return AVERROR(EAGAIN);
FD_ZERO(&rfds);
max_p = 0;
if (rt->rtsp_hd) {
tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
FD_SET(tcp_fd, &rfds);
tcp_fd = url_get_file_handle(rt->rtsp_hd);
p[max_p].fd = tcp_fd;
p[max_p++].events = POLLIN;
} else {
fd_max = 0;
tcp_fd = -1;
}
for (i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st->rtp_handle) {
fd = url_get_file_handle(rtsp_st->rtp_handle);
fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
if (FFMAX(fd, fd_rtcp) > fd_max)
fd_max = FFMAX(fd, fd_rtcp);
FD_SET(fd, &rfds);
FD_SET(fd_rtcp, &rfds);
p[max_p].fd = url_get_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN;
p[max_p].fd = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN;
}
}
tv.tv_sec = 0;
tv.tv_usec = SELECT_TIMEOUT_MS * 1000;
n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
n = poll(p, max_p, POLL_TIMEOUT_MS);
if (n > 0) {
int j = 1 - (tcp_fd == -1);
timeout_cnt = 0;
for (i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st->rtp_handle) {
fd = url_get_file_handle(rtsp_st->rtp_handle);
fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
if (FD_ISSET(fd_rtcp, &rfds) || FD_ISSET(fd, &rfds)) {
if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
if (ret > 0) {
*prtsp_st = rtsp_st;
return ret;
}
}
j+=2;
}
}
#if CONFIG_RTSP_DEMUXER
if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) {
if (tcp_fd != -1 && p[0].revents & POLLIN) {
RTSPMessageHeader reply;
ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);

@ -326,6 +326,11 @@ typedef struct RTSPState {
* The number of returned packets
*/
uint64_t packets;
/**
* Polling array for udp
*/
struct pollfd *p;
} RTSPState;
/**

@ -22,8 +22,8 @@
#include "avformat.h"
#include <sys/time.h>
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#if HAVE_POLL_H
#include <poll.h>
#endif
#include "network.h"
#include "rtsp.h"
@ -172,23 +172,16 @@ static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
{
RTSPState *rt = s->priv_data;
RTSPStream *rtsp_st;
fd_set rfds;
int n, tcp_fd;
struct timeval tv;
int n;
struct pollfd p = {url_get_file_handle(rt->rtsp_hd), POLLIN, 0};
AVFormatContext *rtpctx;
int ret;
tcp_fd = url_get_file_handle(rt->rtsp_hd);
while (1) {
FD_ZERO(&rfds);
FD_SET(tcp_fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
n = select(tcp_fd + 1, &rfds, NULL, NULL, &tv);
n = poll(&p, 1, 0);
if (n <= 0)
break;
if (FD_ISSET(tcp_fd, &rfds)) {
if (p.revents & POLLIN) {
RTSPMessageHeader reply;
/* Don't let ff_rtsp_read_reply handle interleaved packets,

@ -25,8 +25,8 @@
#include "network.h"
#include "os_support.h"
#include "internal.h"
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#if HAVE_POLL_H
#include <poll.h>
#endif
#include <sys/time.h>
@ -183,19 +183,15 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt)
struct SAPState *sap = s->priv_data;
int fd = url_get_file_handle(sap->ann_fd);
int n, ret;
fd_set rfds;
struct timeval tv;
struct pollfd p = {fd, POLLIN, 0};
uint8_t recvbuf[1500];
if (sap->eof)
return AVERROR_EOF;
while (1) {
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
tv.tv_sec = tv.tv_usec = 0;
n = select(fd + 1, &rfds, NULL, NULL, &tv);
if (n <= 0 || !FD_ISSET(fd, &rfds))
n = poll(&p, 1, 0);
if (n <= 0 || !(p.revents & POLLIN))
break;
ret = url_read(sap->ann_fd, recvbuf, sizeof(recvbuf));
if (ret >= 8) {

@ -23,8 +23,8 @@
#include "internal.h"
#include "network.h"
#include "os_support.h"
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#if HAVE_POLL_H
#include <poll.h>
#endif
#include <sys/time.h>
@ -38,9 +38,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
struct addrinfo hints, *ai, *cur_ai;
int port, fd = -1;
TCPContext *s = NULL;
fd_set wfds, efds;
int fd_max, ret;
struct timeval tv;
int ret;
socklen_t optlen;
char hostname[1024],proto[1024],path[1024];
char portstr[10];
@ -73,6 +71,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
redo:
ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
if (ret < 0) {
struct pollfd p = {fd, POLLOUT, 0};
if (ff_neterrno() == FF_NETERROR(EINTR)) {
if (url_interrupt_cb())
goto fail1;
@ -88,15 +87,8 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
ret = AVERROR(EINTR);
goto fail1;
}
fd_max = fd;
FD_ZERO(&wfds);
FD_ZERO(&efds);
FD_SET(fd, &wfds);
FD_SET(fd, &efds);
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
ret = select(fd_max + 1, NULL, &wfds, &efds, &tv);
if (ret > 0 && (FD_ISSET(fd, &wfds) || FD_ISSET(fd, &efds)))
ret = poll(&p, 1, 100);
if (ret > 0)
break;
}
@ -140,20 +132,14 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
static int tcp_read(URLContext *h, uint8_t *buf, int size)
{
TCPContext *s = h->priv_data;
int len, fd_max, ret;
fd_set rfds;
struct timeval tv;
struct pollfd p = {s->fd, POLLIN, 0};
int len, ret;
for (;;) {
if (url_interrupt_cb())
return AVERROR(EINTR);
fd_max = s->fd;
FD_ZERO(&rfds);
FD_SET(s->fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
ret = select(fd_max + 1, &rfds, NULL, NULL, &tv);
if (ret > 0 && FD_ISSET(s->fd, &rfds)) {
ret = poll(&p, 1, 100);
if (ret == 1 && p.revents & POLLIN) {
len = recv(s->fd, buf, size, 0);
if (len < 0) {
if (ff_neterrno() != FF_NETERROR(EINTR) &&
@ -171,21 +157,15 @@ static int tcp_read(URLContext *h, uint8_t *buf, int size)
static int tcp_write(URLContext *h, const uint8_t *buf, int size)
{
TCPContext *s = h->priv_data;
int ret, size1, fd_max, len;
fd_set wfds;
struct timeval tv;
int ret, size1, len;
struct pollfd p = {s->fd, POLLOUT, 0};
size1 = size;
while (size > 0) {
if (url_interrupt_cb())
return AVERROR(EINTR);
fd_max = s->fd;
FD_ZERO(&wfds);
FD_SET(s->fd, &wfds);
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
ret = select(fd_max + 1, NULL, &wfds, NULL, &tv);
if (ret > 0 && FD_ISSET(s->fd, &wfds)) {
ret = poll(&p, 1, 100);
if (ret == 1 && p.revents & POLLOUT) {
len = send(s->fd, buf, size, 0);
if (len < 0) {
if (ff_neterrno() != FF_NETERROR(EINTR) &&

@ -31,8 +31,8 @@
#include "internal.h"
#include "network.h"
#include "os_support.h"
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#if HAVE_POLL_H
#include <poll.h>
#endif
#include <sys/time.h>
@ -432,25 +432,20 @@ 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;
fd_set rfds;
int ret;
struct timeval tv;
for(;;) {
if (url_interrupt_cb())
return AVERROR(EINTR);
FD_ZERO(&rfds);
FD_SET(s->udp_fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv);
ret = poll(&p, 1, 100);
if (ret < 0) {
if (ff_neterrno() == FF_NETERROR(EINTR))
continue;
return AVERROR(EIO);
}
if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds)))
if (!(ret == 1 && p.revents & POLLIN))
continue;
len = recv(s->udp_fd, buf, size, 0);
if (len < 0) {

Loading…
Cancel
Save