mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-03-23 11:29:03 +00:00
os: replace select with poll
Select has limitations on the fd values it could accept and silently breaks when it is reached.
This commit is contained in:
parent
5ce5dbc5f3
commit
a8475bbdb6
@ -236,7 +236,6 @@ int ff_socket_nonblock(int socket, int enable)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_NETWORK */
|
#endif /* CONFIG_NETWORK */
|
||||||
|
|
||||||
#if CONFIG_FFSERVER
|
|
||||||
#if !HAVE_POLL_H
|
#if !HAVE_POLL_H
|
||||||
int poll(struct pollfd *fds, nfds_t numfds, int timeout)
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_POLL_H */
|
#endif /* HAVE_POLL_H */
|
||||||
#endif /* CONFIG_FFSERVER */
|
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "os_support.h"
|
#include "os_support.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#if HAVE_SYS_SELECT_H
|
#if HAVE_POLL_H
|
||||||
#include <sys/select.h>
|
#include <sys/poll.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
@ -221,9 +221,9 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
|
|||||||
RTPContext *s = h->priv_data;
|
RTPContext *s = h->priv_data;
|
||||||
struct sockaddr_storage from;
|
struct sockaddr_storage from;
|
||||||
socklen_t from_len;
|
socklen_t from_len;
|
||||||
int len, fd_max, n;
|
int len, n;
|
||||||
fd_set rfds;
|
struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};
|
||||||
struct timeval tv;
|
|
||||||
#if 0
|
#if 0
|
||||||
for(;;) {
|
for(;;) {
|
||||||
from_len = sizeof(from);
|
from_len = sizeof(from);
|
||||||
@ -242,18 +242,10 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
|
|||||||
if (url_interrupt_cb())
|
if (url_interrupt_cb())
|
||||||
return AVERROR(EINTR);
|
return AVERROR(EINTR);
|
||||||
/* build fdset to listen to RTP and RTCP packets */
|
/* build fdset to listen to RTP and RTCP packets */
|
||||||
FD_ZERO(&rfds);
|
n = poll(p, 2, 100);
|
||||||
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);
|
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
/* first try RTCP */
|
/* first try RTCP */
|
||||||
if (FD_ISSET(s->rtcp_fd, &rfds)) {
|
if (p[1].revents & POLLIN) {
|
||||||
from_len = sizeof(from);
|
from_len = sizeof(from);
|
||||||
len = recvfrom (s->rtcp_fd, buf, size, 0,
|
len = recvfrom (s->rtcp_fd, buf, size, 0,
|
||||||
(struct sockaddr *)&from, &from_len);
|
(struct sockaddr *)&from, &from_len);
|
||||||
@ -266,7 +258,7 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* then RTP */
|
/* then RTP */
|
||||||
if (FD_ISSET(s->rtp_fd, &rfds)) {
|
if (p[0].revents & POLLIN) {
|
||||||
from_len = sizeof(from);
|
from_len = sizeof(from);
|
||||||
len = recvfrom (s->rtp_fd, buf, size, 0,
|
len = recvfrom (s->rtp_fd, buf, size, 0,
|
||||||
(struct sockaddr *)&from, &from_len);
|
(struct sockaddr *)&from, &from_len);
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
#include "avformat.h"
|
#include "avformat.h"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#if HAVE_SYS_SELECT_H
|
#if HAVE_POLL_H
|
||||||
#include <sys/select.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
@ -44,11 +44,11 @@
|
|||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
//#define DEBUG_RTP_TCP
|
//#define DEBUG_RTP_TCP
|
||||||
|
|
||||||
/* Timeout values for socket select, in ms,
|
/* Timeout values for socket poll, in ms,
|
||||||
* and read_packet(), in seconds */
|
* and read_packet(), in seconds */
|
||||||
#define SELECT_TIMEOUT_MS 100
|
#define POLL_TIMEOUT_MS 100
|
||||||
#define READ_PACKET_TIMEOUT_S 10
|
#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 SDP_MAX_SIZE 16384
|
||||||
#define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
|
#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)
|
int ff_sdp_parse(AVFormatContext *s, const char *content)
|
||||||
{
|
{
|
||||||
|
RTSPState *rt = s->priv_data;
|
||||||
const char *p;
|
const char *p;
|
||||||
int letter;
|
int letter;
|
||||||
/* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
|
/* 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')
|
if (*p == '\n')
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1));
|
||||||
|
if (!rt->p) return AVERROR(ENOMEM);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_RTPDEC */
|
#endif /* CONFIG_RTPDEC */
|
||||||
@ -531,6 +539,7 @@ void ff_rtsp_close_streams(AVFormatContext *s)
|
|||||||
av_close_input_stream (rt->asf_ctx);
|
av_close_input_stream (rt->asf_ctx);
|
||||||
rt->asf_ctx = NULL;
|
rt->asf_ctx = NULL;
|
||||||
}
|
}
|
||||||
|
av_free(rt->p);
|
||||||
av_free(rt->recvbuf);
|
av_free(rt->recvbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1554,55 +1563,51 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
|
|||||||
{
|
{
|
||||||
RTSPState *rt = s->priv_data;
|
RTSPState *rt = s->priv_data;
|
||||||
RTSPStream *rtsp_st;
|
RTSPStream *rtsp_st;
|
||||||
fd_set rfds;
|
int n, i, ret, tcp_fd, timeout_cnt = 0;
|
||||||
int fd, fd_rtcp, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0;
|
int max_p = 0;
|
||||||
struct timeval tv;
|
struct pollfd *p = rt->p;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (url_interrupt_cb())
|
if (url_interrupt_cb())
|
||||||
return AVERROR(EINTR);
|
return AVERROR(EINTR);
|
||||||
if (wait_end && wait_end - av_gettime() < 0)
|
if (wait_end && wait_end - av_gettime() < 0)
|
||||||
return AVERROR(EAGAIN);
|
return AVERROR(EAGAIN);
|
||||||
FD_ZERO(&rfds);
|
max_p = 0;
|
||||||
if (rt->rtsp_hd) {
|
if (rt->rtsp_hd) {
|
||||||
tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
|
tcp_fd = url_get_file_handle(rt->rtsp_hd);
|
||||||
FD_SET(tcp_fd, &rfds);
|
p[max_p].fd = tcp_fd;
|
||||||
|
p[max_p++].events = POLLIN;
|
||||||
} else {
|
} else {
|
||||||
fd_max = 0;
|
|
||||||
tcp_fd = -1;
|
tcp_fd = -1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < rt->nb_rtsp_streams; i++) {
|
for (i = 0; i < rt->nb_rtsp_streams; i++) {
|
||||||
rtsp_st = rt->rtsp_streams[i];
|
rtsp_st = rt->rtsp_streams[i];
|
||||||
if (rtsp_st->rtp_handle) {
|
if (rtsp_st->rtp_handle) {
|
||||||
fd = url_get_file_handle(rtsp_st->rtp_handle);
|
p[max_p].fd = url_get_file_handle(rtsp_st->rtp_handle);
|
||||||
fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
|
p[max_p++].events = POLLIN;
|
||||||
if (FFMAX(fd, fd_rtcp) > fd_max)
|
p[max_p].fd = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
|
||||||
fd_max = FFMAX(fd, fd_rtcp);
|
p[max_p++].events = POLLIN;
|
||||||
FD_SET(fd, &rfds);
|
|
||||||
FD_SET(fd_rtcp, &rfds);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tv.tv_sec = 0;
|
n = poll(p, max_p, POLL_TIMEOUT_MS);
|
||||||
tv.tv_usec = SELECT_TIMEOUT_MS * 1000;
|
|
||||||
n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
|
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
|
int j = 1 - (tcp_fd == -1);
|
||||||
timeout_cnt = 0;
|
timeout_cnt = 0;
|
||||||
for (i = 0; i < rt->nb_rtsp_streams; i++) {
|
for (i = 0; i < rt->nb_rtsp_streams; i++) {
|
||||||
rtsp_st = rt->rtsp_streams[i];
|
rtsp_st = rt->rtsp_streams[i];
|
||||||
if (rtsp_st->rtp_handle) {
|
if (rtsp_st->rtp_handle) {
|
||||||
fd = url_get_file_handle(rtsp_st->rtp_handle);
|
if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
|
||||||
fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
|
|
||||||
if (FD_ISSET(fd_rtcp, &rfds) || FD_ISSET(fd, &rfds)) {
|
|
||||||
ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
|
ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
*prtsp_st = rtsp_st;
|
*prtsp_st = rtsp_st;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
j+=2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if CONFIG_RTSP_DEMUXER
|
#if CONFIG_RTSP_DEMUXER
|
||||||
if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) {
|
if (tcp_fd != -1 && p[0].revents & POLLIN) {
|
||||||
RTSPMessageHeader reply;
|
RTSPMessageHeader reply;
|
||||||
|
|
||||||
ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);
|
ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);
|
||||||
|
@ -326,6 +326,11 @@ typedef struct RTSPState {
|
|||||||
* The number of returned packets
|
* The number of returned packets
|
||||||
*/
|
*/
|
||||||
uint64_t packets;
|
uint64_t packets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Polling array for udp
|
||||||
|
*/
|
||||||
|
struct pollfd *p;
|
||||||
} RTSPState;
|
} RTSPState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
#include "avformat.h"
|
#include "avformat.h"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#if HAVE_SYS_SELECT_H
|
#if HAVE_POLL_H
|
||||||
#include <sys/select.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "rtsp.h"
|
#include "rtsp.h"
|
||||||
@ -172,23 +172,16 @@ static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
{
|
{
|
||||||
RTSPState *rt = s->priv_data;
|
RTSPState *rt = s->priv_data;
|
||||||
RTSPStream *rtsp_st;
|
RTSPStream *rtsp_st;
|
||||||
fd_set rfds;
|
int n;
|
||||||
int n, tcp_fd;
|
struct pollfd p = {url_get_file_handle(rt->rtsp_hd), POLLIN, 0};
|
||||||
struct timeval tv;
|
|
||||||
AVFormatContext *rtpctx;
|
AVFormatContext *rtpctx;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
tcp_fd = url_get_file_handle(rt->rtsp_hd);
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
FD_ZERO(&rfds);
|
n = poll(&p, 1, 0);
|
||||||
FD_SET(tcp_fd, &rfds);
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
n = select(tcp_fd + 1, &rfds, NULL, NULL, &tv);
|
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
break;
|
break;
|
||||||
if (FD_ISSET(tcp_fd, &rfds)) {
|
if (p.revents & POLLIN) {
|
||||||
RTSPMessageHeader reply;
|
RTSPMessageHeader reply;
|
||||||
|
|
||||||
/* Don't let ff_rtsp_read_reply handle interleaved packets,
|
/* Don't let ff_rtsp_read_reply handle interleaved packets,
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "os_support.h"
|
#include "os_support.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#if HAVE_SYS_SELECT_H
|
#if HAVE_POLL_H
|
||||||
#include <sys/select.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
@ -183,19 +183,15 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
struct SAPState *sap = s->priv_data;
|
struct SAPState *sap = s->priv_data;
|
||||||
int fd = url_get_file_handle(sap->ann_fd);
|
int fd = url_get_file_handle(sap->ann_fd);
|
||||||
int n, ret;
|
int n, ret;
|
||||||
fd_set rfds;
|
struct pollfd p = {fd, POLLIN, 0};
|
||||||
struct timeval tv;
|
|
||||||
uint8_t recvbuf[1500];
|
uint8_t recvbuf[1500];
|
||||||
|
|
||||||
if (sap->eof)
|
if (sap->eof)
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
FD_ZERO(&rfds);
|
n = poll(&p, 1, 0);
|
||||||
FD_SET(fd, &rfds);
|
if (n <= 0 || !(p.revents & POLLIN))
|
||||||
tv.tv_sec = tv.tv_usec = 0;
|
|
||||||
n = select(fd + 1, &rfds, NULL, NULL, &tv);
|
|
||||||
if (n <= 0 || !FD_ISSET(fd, &rfds))
|
|
||||||
break;
|
break;
|
||||||
ret = url_read(sap->ann_fd, recvbuf, sizeof(recvbuf));
|
ret = url_read(sap->ann_fd, recvbuf, sizeof(recvbuf));
|
||||||
if (ret >= 8) {
|
if (ret >= 8) {
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "os_support.h"
|
#include "os_support.h"
|
||||||
#if HAVE_SYS_SELECT_H
|
#if HAVE_POLL_H
|
||||||
#include <sys/select.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/time.h>
|
#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;
|
struct addrinfo hints, *ai, *cur_ai;
|
||||||
int port, fd = -1;
|
int port, fd = -1;
|
||||||
TCPContext *s = NULL;
|
TCPContext *s = NULL;
|
||||||
fd_set wfds, efds;
|
int ret;
|
||||||
int fd_max, ret;
|
|
||||||
struct timeval tv;
|
|
||||||
socklen_t optlen;
|
socklen_t optlen;
|
||||||
char hostname[1024],proto[1024],path[1024];
|
char hostname[1024],proto[1024],path[1024];
|
||||||
char portstr[10];
|
char portstr[10];
|
||||||
@ -73,6 +71,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
|
|||||||
redo:
|
redo:
|
||||||
ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
|
ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
struct pollfd p = {fd, POLLOUT, 0};
|
||||||
if (ff_neterrno() == FF_NETERROR(EINTR)) {
|
if (ff_neterrno() == FF_NETERROR(EINTR)) {
|
||||||
if (url_interrupt_cb())
|
if (url_interrupt_cb())
|
||||||
goto fail1;
|
goto fail1;
|
||||||
@ -88,15 +87,8 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
|
|||||||
ret = AVERROR(EINTR);
|
ret = AVERROR(EINTR);
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
fd_max = fd;
|
ret = poll(&p, 1, 100);
|
||||||
FD_ZERO(&wfds);
|
if (ret > 0)
|
||||||
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)))
|
|
||||||
break;
|
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)
|
static int tcp_read(URLContext *h, uint8_t *buf, int size)
|
||||||
{
|
{
|
||||||
TCPContext *s = h->priv_data;
|
TCPContext *s = h->priv_data;
|
||||||
int len, fd_max, ret;
|
struct pollfd p = {s->fd, POLLIN, 0};
|
||||||
fd_set rfds;
|
int len, ret;
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (url_interrupt_cb())
|
if (url_interrupt_cb())
|
||||||
return AVERROR(EINTR);
|
return AVERROR(EINTR);
|
||||||
fd_max = s->fd;
|
ret = poll(&p, 1, 100);
|
||||||
FD_ZERO(&rfds);
|
if (ret == 1 && p.revents & POLLIN) {
|
||||||
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)) {
|
|
||||||
len = recv(s->fd, buf, size, 0);
|
len = recv(s->fd, buf, size, 0);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (ff_neterrno() != FF_NETERROR(EINTR) &&
|
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)
|
static int tcp_write(URLContext *h, const uint8_t *buf, int size)
|
||||||
{
|
{
|
||||||
TCPContext *s = h->priv_data;
|
TCPContext *s = h->priv_data;
|
||||||
int ret, size1, fd_max, len;
|
int ret, size1, len;
|
||||||
fd_set wfds;
|
struct pollfd p = {s->fd, POLLOUT, 0};
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
size1 = size;
|
size1 = size;
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
if (url_interrupt_cb())
|
if (url_interrupt_cb())
|
||||||
return AVERROR(EINTR);
|
return AVERROR(EINTR);
|
||||||
fd_max = s->fd;
|
ret = poll(&p, 1, 100);
|
||||||
FD_ZERO(&wfds);
|
if (ret == 1 && p.revents & POLLOUT) {
|
||||||
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)) {
|
|
||||||
len = send(s->fd, buf, size, 0);
|
len = send(s->fd, buf, size, 0);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (ff_neterrno() != FF_NETERROR(EINTR) &&
|
if (ff_neterrno() != FF_NETERROR(EINTR) &&
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "os_support.h"
|
#include "os_support.h"
|
||||||
#if HAVE_SYS_SELECT_H
|
#if HAVE_POLL_H
|
||||||
#include <sys/select.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/time.h>
|
#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)
|
static int udp_read(URLContext *h, uint8_t *buf, int size)
|
||||||
{
|
{
|
||||||
UDPContext *s = h->priv_data;
|
UDPContext *s = h->priv_data;
|
||||||
|
struct pollfd p = {s->udp_fd, POLLIN, 0};
|
||||||
int len;
|
int len;
|
||||||
fd_set rfds;
|
|
||||||
int ret;
|
int ret;
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (url_interrupt_cb())
|
if (url_interrupt_cb())
|
||||||
return AVERROR(EINTR);
|
return AVERROR(EINTR);
|
||||||
FD_ZERO(&rfds);
|
ret = poll(&p, 1, 100);
|
||||||
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);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ff_neterrno() == FF_NETERROR(EINTR))
|
if (ff_neterrno() == FF_NETERROR(EINTR))
|
||||||
continue;
|
continue;
|
||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
}
|
}
|
||||||
if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds)))
|
if (!(ret == 1 && p.revents & POLLIN))
|
||||||
continue;
|
continue;
|
||||||
len = recv(s->udp_fd, buf, size, 0);
|
len = recv(s->udp_fd, buf, size, 0);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user