You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-11-23 21:54:53 +02:00
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.
This commit is contained in:
committed by
Clément Bœsch
parent
77d2cb8874
commit
473f0f75a1
@@ -43,7 +43,6 @@ typedef struct ThreadContext {
|
|||||||
AVFilterContext *ctx;
|
AVFilterContext *ctx;
|
||||||
void *arg;
|
void *arg;
|
||||||
int *rets;
|
int *rets;
|
||||||
int nb_rets;
|
|
||||||
int nb_jobs;
|
int nb_jobs;
|
||||||
|
|
||||||
pthread_cond_t last_job_cond;
|
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 our_job = c->nb_jobs;
|
||||||
int nb_threads = c->nb_threads;
|
int nb_threads = c->nb_threads;
|
||||||
unsigned int last_execute = 0;
|
unsigned int last_execute = 0;
|
||||||
int self_id;
|
int ret, self_id;
|
||||||
|
|
||||||
pthread_mutex_lock(&c->current_job_lock);
|
pthread_mutex_lock(&c->current_job_lock);
|
||||||
self_id = c->current_job++;
|
self_id = c->current_job++;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (our_job >= c->nb_jobs) {
|
while (our_job >= c->nb_jobs) {
|
||||||
if (c->current_job == nb_threads + 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);
|
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);
|
pthread_mutex_lock(&c->current_job_lock);
|
||||||
our_job = c->current_job++;
|
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)
|
void *arg, int *ret, int nb_jobs)
|
||||||
{
|
{
|
||||||
ThreadContext *c = ctx->graph->internal->thread;
|
ThreadContext *c = ctx->graph->internal->thread;
|
||||||
int dummy_ret;
|
|
||||||
|
|
||||||
if (nb_jobs <= 0)
|
if (nb_jobs <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -129,13 +130,7 @@ static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func,
|
|||||||
c->ctx = ctx;
|
c->ctx = ctx;
|
||||||
c->arg = arg;
|
c->arg = arg;
|
||||||
c->func = func;
|
c->func = func;
|
||||||
if (ret) {
|
c->rets = ret;
|
||||||
c->rets = ret;
|
|
||||||
c->nb_rets = nb_jobs;
|
|
||||||
} else {
|
|
||||||
c->rets = &dummy_ret;
|
|
||||||
c->nb_rets = 1;
|
|
||||||
}
|
|
||||||
c->current_execute++;
|
c->current_execute++;
|
||||||
|
|
||||||
pthread_cond_broadcast(&c->current_job_cond);
|
pthread_cond_broadcast(&c->current_job_cond);
|
||||||
|
|||||||
Reference in New Issue
Block a user