diff options
author | Anton Khirnov <anton@khirnov.net> | 2016-07-17 23:30:52 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2016-10-02 19:35:23 +0200 |
commit | db2733256db323e4b88a34b135320f33274148e2 (patch) | |
tree | ffd53b84f90c7a4da7da96df20c33758b06e7a30 | |
parent | 8385ba53f115401a67a4748c0d107769ebfb2941 (diff) | |
download | ffmpeg-streaming-db2733256db323e4b88a34b135320f33274148e2.zip ffmpeg-streaming-db2733256db323e4b88a34b135320f33274148e2.tar.gz |
pthread_frame: use a thread-safe way for signalling threads to die
Current code uses a plain int in a racy way, which is UB.
-rw-r--r-- | libavcodec/pthread_frame.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index c72da53..0549f42 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -90,6 +90,8 @@ typedef struct PerThreadContext { AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer() int requested_flags; ///< flags passed to get_buffer() for requested_frame + + int die; ///< Set when the thread should exit. } PerThreadContext; /** @@ -108,8 +110,6 @@ typedef struct FrameThreadContext { * Set for the first N packets, where N is the number of threads. * While it is set, ff_thread_en/decode_frame won't return any results. */ - - int die; ///< Set when threads should exit. } FrameThreadContext; /** @@ -122,20 +122,22 @@ typedef struct FrameThreadContext { static attribute_align_arg void *frame_worker_thread(void *arg) { PerThreadContext *p = arg; - FrameThreadContext *fctx = p->parent; AVCodecContext *avctx = p->avctx; const AVCodec *codec = avctx->codec; while (1) { - if (p->state == STATE_INPUT_READY && !fctx->die) { + if (p->state == STATE_INPUT_READY) { pthread_mutex_lock(&p->mutex); - while (p->state == STATE_INPUT_READY && !fctx->die) + while (p->state == STATE_INPUT_READY) { + if (p->die) { + pthread_mutex_unlock(&p->mutex); + goto die; + } pthread_cond_wait(&p->input_cond, &p->mutex); + } pthread_mutex_unlock(&p->mutex); } - if (fctx->die) break; - if (!codec->update_thread_context && avctx->thread_safe_callbacks) ff_thread_finish_setup(avctx); @@ -161,6 +163,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg) pthread_mutex_unlock(&p->mutex); } +die: return NULL; } @@ -504,12 +507,11 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) if (fctx->prev_thread && fctx->prev_thread != fctx->threads) update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0); - fctx->die = 1; - for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; pthread_mutex_lock(&p->mutex); + p->die = 1; pthread_cond_signal(&p->input_cond); pthread_mutex_unlock(&p->mutex); |