summaryrefslogtreecommitdiff
path: root/libavformat/udp.c
diff options
context:
space:
mode:
authorNicolas George <nicolas.george@normalesup.org>2012-03-15 13:03:38 +0100
committerNicolas George <nicolas.george@normalesup.org>2012-03-22 17:36:23 +0100
commitaa1297882fc95b3f301d39f3a74730ef72f44b70 (patch)
treee4f688e689d0f8e78c0919a7ff0da1d1077f2d88 /libavformat/udp.c
parent4246032216181c778f7ddf7f2e062cada2ef346d (diff)
udp: use pthread_cancel instead of a shared flag.
It allows to exit the thread immediately instead of waiting for select to timeout (one second in the current code).
Diffstat (limited to 'libavformat/udp.c')
-rw-r--r--libavformat/udp.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/libavformat/udp.c b/libavformat/udp.c
index 84edece69d..0a831e8ea5 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -73,7 +73,6 @@ typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
int thread_started;
- volatile int exit_thread;
#endif
uint8_t tmp[UDP_MAX_PKT_SIZE+4];
int remaining_in_dg;
@@ -330,8 +329,10 @@ static void *circular_buffer_task( void *_URLContext)
UDPContext *s = h->priv_data;
fd_set rfds;
struct timeval tv;
+ int old_cancelstate;
- while(!s->exit_thread) {
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
+ while(1) {
int left;
int ret;
int len;
@@ -340,7 +341,9 @@ static void *circular_buffer_task( void *_URLContext)
FD_SET(s->udp_fd, &rfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate);
ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv);
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
if (ret < 0) {
if (ff_neterrno() == AVERROR(EINTR))
continue;
@@ -355,7 +358,12 @@ static void *circular_buffer_task( void *_URLContext)
/* Whats the minimum we can read so that we dont comletely fill the buffer */
left = av_fifo_space(s->fifo);
+ /* Blocking operations are always cancellation points;
+ see "General Information" / "Thread Cancelation Overview"
+ in Single Unix. */
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate);
len = recv(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0);
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
if (len < 0) {
if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
s->circular_buffer_error = AVERROR(EIO);
@@ -669,7 +677,7 @@ static int udp_close(URLContext *h)
av_fifo_free(s->fifo);
#if HAVE_PTHREADS
if (s->thread_started) {
- s->exit_thread = 1;
+ pthread_cancel(s->circular_buffer_thread);
ret = pthread_join(s->circular_buffer_thread, NULL);
if (ret != 0)
av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", strerror(ret));