[FFmpeg-devel] [PATCH] Replace select with poll
Luca Barbato
lu_zero
Mon Jan 24 11:07:04 CET 2011
Select has limitations on the fd values it could accept and silently
breaks when it is reached.
---
libavformat/os_support.c | 3 --
libavformat/rtpproto.c | 24 +++++++---------------
libavformat/rtsp.c | 49 +++++++++++++++++++++------------------------
libavformat/rtspenc.c | 19 +++++------------
libavformat/sapdec.c | 14 ++++--------
libavformat/tcp.c | 48 +++++++++++++-------------------------------
libavformat/udp.c | 15 ++++---------
7 files changed, 61 insertions(+), 111 deletions(-)
diff --git a/libavformat/os_support.c b/libavformat/os_support.c
index 83f0820..70cca92 100644
--- a/libavformat/os_support.c
+++ b/libavformat/os_support.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 */
-
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index 0e2abf5..a2303a6 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -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);
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 2b61b89..323ea3f 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -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
@@ -1529,55 +1529,52 @@ 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;
+ //FIXME use malloc
+ struct pollfd p[2*rt->nb_rtsp_streams+1];
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;
+ //FIXME this loop should be simplified
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) {
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);
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index 3a0b2c7..3de2f6b 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -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,
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index 701eae2..f91aaf4 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -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) {
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index 14b5e19..530d802 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -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) &&
diff --git a/libavformat/udp.c b/libavformat/udp.c
index 0b62c6d..810c3ee 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -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) {
--
1.7.2.2
More information about the ffmpeg-devel
mailing list