summaryrefslogtreecommitdiff
path: root/libavcodec/pthread_frame.c
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2017-04-03 09:48:53 -0400
committerRonald S. Bultje <rsbultje@gmail.com>2017-04-03 09:48:53 -0400
commit1269cd5b6f540bef5913bf134d2f461aac50d70b (patch)
tree040c768b7b4f885adffca8dd53ccbc96e18f82b9 /libavcodec/pthread_frame.c
parent76d8c77430e9e0110623705bfb54d922cc2ac3ea (diff)
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)
Diffstat (limited to 'libavcodec/pthread_frame.c')
-rw-r--r--libavcodec/pthread_frame.c14
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;