diff options
author | Ronald S. Bultje <rsbultje@gmail.com> | 2017-04-03 09:48:53 -0400 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2017-04-13 02:29:26 +0200 |
commit | b51217381dd748fd831ba9403cdcdc8277bd63d5 (patch) | |
tree | 477a4c67d8160f5fead8aacadae30da9d589d317 | |
parent | f5f0b2f44ce9df08f7a79b32d9209b23ba6b3447 (diff) | |
download | ffmpeg-b51217381dd748fd831ba9403cdcdc8277bd63d5.tar.gz |
pthread_frame: call update_context_from_user() after acquiring lock.
Otherwise the thread may still be in the middle of decoding a previous
frame, which would effectively trigger a race condition on any field
concurrently read and written.
In practice, this fixes tsan warnings like the following:
WARNING: ThreadSanitizer: data race (pid=17380)
Write of size 4 at 0x7d64000160fc by main thread:
#0 update_context_from_user src/libavcodec/pthread_frame.c:335 (ffmpeg+0x000000dca515)
[..]
Previous read of size 4 at 0x7d64000160fc by thread T2 (mutexes: write M1821):
#0 ff_thread_report_progress src/libavcodec/pthread_frame.c:565 (ffmpeg+0x000000dcb08a)
(cherry picked from commit 1269cd5b6f540bef5913bf134d2f461aac50d70b)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavcodec/pthread_frame.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 4e1ad9d686..9a6b83ac45 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -380,7 +380,8 @@ static void release_delayed_buffers(PerThreadContext *p) } } -static int submit_packet(PerThreadContext *p, AVPacket *avpkt) +static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, + AVPacket *avpkt) { FrameThreadContext *fctx = p->parent; PerThreadContext *prev_thread = fctx->prev_thread; @@ -392,6 +393,12 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) pthread_mutex_lock(&p->mutex); + ret = update_context_from_user(p->avctx, user_avctx); + if (ret) { + pthread_mutex_unlock(&p->mutex); + return ret; + } + release_delayed_buffers(p); if (prev_thread) { @@ -480,10 +487,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, */ p = &fctx->threads[fctx->next_decoding]; - err = update_context_from_user(p->avctx, avctx); - if (err) - goto finish; - err = submit_packet(p, avpkt); + err = submit_packet(p, avctx, avpkt); if (err) goto finish; |