You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
udp: fix non-blocking and interrupt handling.
In non-blocking mode, lowest-level read protocols are supposed block only for a short amount of time to let retry_transfer_wrapper() check for interrupts. Also, checking the interrupt_callback in the receiving thread is wrong, as interrupt_callback is not guaranteed to be thread-safe and the job is already done by retry_transfer_wrapper(). The error code was also incorrect. Bug reported by Andrey Utkin.
This commit is contained in:
@@ -336,11 +336,6 @@ static void *circular_buffer_task( void *_URLContext)
|
|||||||
int ret;
|
int ret;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (ff_check_interrupt(&h->interrupt_callback)) {
|
|
||||||
s->circular_buffer_error = AVERROR(EINTR);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(s->udp_fd, &rfds);
|
FD_SET(s->udp_fd, &rfds);
|
||||||
tv.tv_sec = 1;
|
tv.tv_sec = 1;
|
||||||
@@ -590,7 +585,7 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
|
|||||||
{
|
{
|
||||||
UDPContext *s = h->priv_data;
|
UDPContext *s = h->priv_data;
|
||||||
int ret;
|
int ret;
|
||||||
int avail;
|
int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;
|
||||||
|
|
||||||
#if HAVE_PTHREADS
|
#if HAVE_PTHREADS
|
||||||
if (s->fifo) {
|
if (s->fifo) {
|
||||||
@@ -614,12 +609,19 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
|
|||||||
} else if(s->circular_buffer_error){
|
} else if(s->circular_buffer_error){
|
||||||
pthread_mutex_unlock(&s->mutex);
|
pthread_mutex_unlock(&s->mutex);
|
||||||
return s->circular_buffer_error;
|
return s->circular_buffer_error;
|
||||||
} else if(h->flags & AVIO_FLAG_NONBLOCK) {
|
} else if(nonblock) {
|
||||||
pthread_mutex_unlock(&s->mutex);
|
pthread_mutex_unlock(&s->mutex);
|
||||||
return AVERROR(EAGAIN);
|
return AVERROR(EAGAIN);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pthread_cond_wait(&s->cond, &s->mutex);
|
/* FIXME: using the monotonic clock would be better,
|
||||||
|
but it does not exist on all supported platforms. */
|
||||||
|
int64_t t = av_gettime() + 100000;
|
||||||
|
struct timespec tv = { .tv_sec = t / 1000000,
|
||||||
|
.tv_nsec = (t % 1000000) * 1000 };
|
||||||
|
if (pthread_cond_timedwait(&s->cond, &s->mutex, &tv) < 0)
|
||||||
|
return AVERROR(errno == ETIMEDOUT ? EAGAIN : errno);
|
||||||
|
nonblock = 1;
|
||||||
}
|
}
|
||||||
} while( 1);
|
} while( 1);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user