Opened 12 years ago

Closed 12 years ago

#1026 closed defect (fixed)

libavformat::av_read_frame does not return waiting for udp packets when interrupted

Reported by: asif Owned by:
Priority: important Component: avformat
Version: 0.10 Keywords: deadlock, interrupt
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Steps to reproduce:

  1. Start receiving udp stream.
  2. Stop the incoming udp stream transmitter.
  3. udp.c::udp_read will wait for udp.c::circular_buffer_task at pthread_cond_wait(&s->cond, &s->mutex);
  4. Interrupt udp.c::circular_buffer_task by returning 1 from interrupt_callback. Circular buffer will exit and signal udp_read as well. But the return value is EINTR
  5. udp.c::udp_read will return to avio.c::retry_transfer_wrapper. This function is ignoring the error and will call udp_read again.

Change History (3)

comment:1 by asif, 12 years ago

Possible fix:

  1. Revert the changes that were made in the following commit:
author	Baptiste Coudurier <baptiste.coudurier@gmail.com>

	Fri, 4 Mar 2011 04:33:44 +0100 (19:33 -0800)	
committer	Baptiste Coudurier <baptiste.coudurier@gmail.com>

	Fri, 4 Mar 2011 04:34:59 +0100 (19:34 -0800)	


File: libavformat/avio.c

diff --git a/libavformat/avio.c b/libavformat/avio.c
index a19ec37..cf07c6d 100644 (file)
--- a/libavformat/avio.c

+++ b/libavformat/avio.c
@@ -214,8 +214,6 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int
 
     len = 0;
     while (len < size_min) {
-        if (url_interrupt_cb())
-            return AVERROR(EINTR);
         ret = transfer_func(h, buf+len, size-len);
         if (ret == AVERROR(EINTR))
             continue;

  1. Modify libavformat/avio.c::retry_transfer_wrapper as below
     len = 0;
     while (len < size_min) {
         ret = transfer_func(h, buf+len, size-len);
         if (ret == AVERROR(EINTR))
-            continue;
+            return AVERROR(EINTR);

  1. Or, return Another error from libavformat/udp.c::circular_buffer_task e.g. EIO
Last edited 12 years ago by asif (previous) (diff)

comment:2 by reimar, 12 years ago

The full commit message suggests that a more reasonable solution would be to only allow interrupting read-only URLs:

commit aa612fbb99f6246913a789afde5a26f70c5a9159
Author: Baptiste Coudurier <baptiste.coudurier@gmail.com>
Date:   Fri Mar 4 23:43:02 2011 +0100

    In retry_transfer_wrapper, do not check url_interrupt_cb, causes problems
    when writing and pressing q during encoding. Instead, check url_interrupt_cb
    at the end.
    
    Note that when a protocol is interrupted by url_interrupt_cb, some data may
    be silently discarded: the protocol context is not suitable for anything
    anymore.

comment:3 by reimar, 12 years ago

Resolution: fixed
Status: newclosed

This has actually been fixed in 463705bd1c644bbdded7bcf9f619bcb4203d562f a month ago.

Note: See TracTickets for help on using tickets.