summaryrefslogtreecommitdiff
path: root/libavfilter/pthread.c
diff options
context:
space:
mode:
authorClément Bœsch <cboesch@gopro.com>2017-03-28 18:00:02 +0200
committerClément Bœsch <u@pkh.me>2017-03-28 23:47:24 +0200
commit473f0f75a16b4d37bdaa943f75e4ae249212c1ba (patch)
tree7ea7b4ff12a77583a180e0bbb59bc8e1129a5de1 /libavfilter/pthread.c
parent77d2cb88741a9ac6ab6a3c53b32b01cec07b99b2 (diff)
downloadffmpeg-473f0f75a16b4d37bdaa943f75e4ae249212c1ba.tar.gz
lavfi: fix race when func rets holder is NULL
If ret is NULL, a dummy common holder is created to hold *all* the parallel function returns, which gets written concurrently. This commit simplify the whole logic by simply not writing to that holder when not set.
Diffstat (limited to 'libavfilter/pthread.c')
-rw-r--r--libavfilter/pthread.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c
index ccb915eae5..c7a00210d6 100644
--- a/libavfilter/pthread.c
+++ b/libavfilter/pthread.c
@@ -43,7 +43,6 @@ typedef struct ThreadContext {
AVFilterContext *ctx;
void *arg;
int *rets;
- int nb_rets;
int nb_jobs;
pthread_cond_t last_job_cond;
@@ -60,10 +59,11 @@ static void* attribute_align_arg worker(void *v)
int our_job = c->nb_jobs;
int nb_threads = c->nb_threads;
unsigned int last_execute = 0;
- int self_id;
+ int ret, self_id;
pthread_mutex_lock(&c->current_job_lock);
self_id = c->current_job++;
+
for (;;) {
while (our_job >= c->nb_jobs) {
if (c->current_job == nb_threads + c->nb_jobs)
@@ -81,7 +81,9 @@ static void* attribute_align_arg worker(void *v)
}
pthread_mutex_unlock(&c->current_job_lock);
- c->rets[our_job % c->nb_rets] = c->func(c->ctx, c->arg, our_job, c->nb_jobs);
+ ret = c->func(c->ctx, c->arg, our_job, c->nb_jobs);
+ if (c->rets)
+ c->rets[our_job % c->nb_jobs] = ret;
pthread_mutex_lock(&c->current_job_lock);
our_job = c->current_job++;
@@ -117,7 +119,6 @@ static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func,
void *arg, int *ret, int nb_jobs)
{
ThreadContext *c = ctx->graph->internal->thread;
- int dummy_ret;
if (nb_jobs <= 0)
return 0;
@@ -129,13 +130,7 @@ static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func,
c->ctx = ctx;
c->arg = arg;
c->func = func;
- if (ret) {
- c->rets = ret;
- c->nb_rets = nb_jobs;
- } else {
- c->rets = &dummy_ret;
- c->nb_rets = 1;
- }
+ c->rets = ret;
c->current_execute++;
pthread_cond_broadcast(&c->current_job_cond);