ref: 50a2da6d6d6ec151a9bd44942095303c6a7cdf7f
parent: 4679305e1c34cf0de27e7782d3bdc7e19923701a
author: Janne Grunau <[email protected]>
date: Thu Feb 7 18:40:35 EST 2019
clean up threads on dav1d_open failures
--- a/src/decode.c
+++ b/src/decode.c
@@ -2594,8 +2594,12 @@
n < f->frame_hdr->tiling.cols * f->frame_hdr->tiling.rows; n++)
{
Dav1dTileState *const ts = &f->ts[n];
- pthread_mutex_init(&ts->tile_thread.lock, NULL);
- pthread_cond_init(&ts->tile_thread.cond, NULL);
+ if (pthread_mutex_init(&ts->tile_thread.lock, NULL)) goto error;
+ if (pthread_cond_init(&ts->tile_thread.cond, NULL)) {
+ pthread_mutex_destroy(&ts->tile_thread.lock);
+ goto error;
+ }
+ f->n_ts = n + 1;
}
if (c->n_fc > 1) {
freep(&f->frame_thread.tile_start_off);
--- a/src/internal.h
+++ b/src/internal.h
@@ -230,6 +230,7 @@
int tasks_left, num_tasks;
int (*task_idx_to_sby_and_tile_idx)[2];
int titsati_sz, titsati_init[3];
+ int inited;
} tile_thread;
};
--- a/src/lib.c
+++ b/src/lib.c
@@ -69,6 +69,8 @@
s->all_layers = 1; // just until the tests are adjusted
}
+static void close_internal(Dav1dContext **const c_out, int flush);
+
int dav1d_open(Dav1dContext **const c_out,
const Dav1dSettings *const s)
{
@@ -119,9 +121,17 @@
if (!f->tc) goto error;
memset(f->tc, 0, sizeof(*f->tc) * s->n_tile_threads);
if (f->n_tc > 1) {
- pthread_mutex_init(&f->tile_thread.lock, NULL);
- pthread_cond_init(&f->tile_thread.cond, NULL);
- pthread_cond_init(&f->tile_thread.icond, NULL);
+ if (pthread_mutex_init(&f->tile_thread.lock, NULL)) goto error;
+ if (pthread_cond_init(&f->tile_thread.cond, NULL)) {
+ pthread_mutex_destroy(&f->tile_thread.lock);
+ goto error;
+ }
+ if (pthread_cond_init(&f->tile_thread.icond, NULL)) {
+ pthread_mutex_destroy(&f->tile_thread.lock);
+ pthread_cond_destroy(&f->tile_thread.cond);
+ goto error;
+ }
+ f->tile_thread.inited = 1;
}
for (int m = 0; m < s->n_tile_threads; m++) {
Dav1dTileContext *const t = &f->tc[m];
@@ -135,18 +145,34 @@
dav1d_alloc_aligned(320 * (256 + 7) * sizeof(uint16_t), 32);
if (!t->emu_edge) goto error;
if (f->n_tc > 1) {
- pthread_mutex_init(&t->tile_thread.td.lock, NULL);
- pthread_cond_init(&t->tile_thread.td.cond, NULL);
+ if (pthread_mutex_init(&t->tile_thread.td.lock, NULL)) goto error;
+ if (pthread_cond_init(&t->tile_thread.td.cond, NULL)) {
+ pthread_mutex_destroy(&t->tile_thread.td.lock);
+ goto error;
+ }
t->tile_thread.fttd = &f->tile_thread;
- pthread_create(&t->tile_thread.td.thread, NULL, dav1d_tile_task, t);
+ if (pthread_create(&t->tile_thread.td.thread, NULL, dav1d_tile_task, t)) {
+ pthread_cond_destroy(&t->tile_thread.td.cond);
+ pthread_mutex_destroy(&t->tile_thread.td.lock);
+ goto error;
+ }
+ t->tile_thread.td.inited = 1;
}
}
f->libaom_cm = av1_alloc_ref_mv_common();
if (!f->libaom_cm) goto error;
if (c->n_fc > 1) {
- pthread_mutex_init(&f->frame_thread.td.lock, NULL);
- pthread_cond_init(&f->frame_thread.td.cond, NULL);
- pthread_create(&f->frame_thread.td.thread, NULL, dav1d_frame_task, f);
+ if (pthread_mutex_init(&f->frame_thread.td.lock, NULL)) goto error;
+ if (pthread_cond_init(&f->frame_thread.td.cond, NULL)) {
+ pthread_mutex_destroy(&f->frame_thread.td.lock);
+ goto error;
+ }
+ if (pthread_create(&f->frame_thread.td.thread, NULL, dav1d_frame_task, f)) {
+ pthread_cond_destroy(&f->frame_thread.td.cond);
+ pthread_mutex_destroy(&f->frame_thread.td.lock);
+ goto error;
+ }
+ f->frame_thread.td.inited = 1;
}
}
@@ -159,26 +185,7 @@
return 0;
error:
- if (c) {
- if (c->fc) {
- for (unsigned n = 0; n < c->n_fc; n++) {
- if (c->fc[n].tc) {
- for (int m = 0; m < s->n_tile_threads; m++) {
- Dav1dTileContext *const t = &c->fc[n].tc[m];
- dav1d_free_aligned(t->cf);
- dav1d_free_aligned(t->scratch.mem);
- dav1d_free_aligned(t->emu_edge);
- }
- dav1d_free_aligned(c->fc[n].tc);
- }
- if (c->fc[n].libaom_cm) av1_free_ref_mv_common(c->fc[n].libaom_cm);
- }
- dav1d_free_aligned(c->fc);
- }
- if (c->n_fc > 1) free(c->frame_thread.out_delayed);
- dav1d_log(c, "Failed to allocate memory: %s\n", strerror(errno));
- dav1d_freep_aligned(c_out);
- }
+ if (c) close_internal(c_out, 0);
return -ENOMEM;
}
@@ -415,16 +422,20 @@
void dav1d_close(Dav1dContext **const c_out) {
validate_input(c_out != NULL);
+ close_internal(c_out, 1);
+}
+static void close_internal(Dav1dContext **const c_out, int flush) {
Dav1dContext *const c = *c_out;
if (!c) return;
- dav1d_flush(c);
- for (unsigned n = 0; n < c->n_fc; n++) {
+ if (flush) dav1d_flush(c);
+
+ for (unsigned n = 0; c->fc && n < c->n_fc; n++) {
Dav1dFrameContext *const f = &c->fc[n];
// clean-up threading stuff
- if (c->n_fc > 1) {
+ if (c->n_fc > 1 && f->frame_thread.td.inited) {
pthread_mutex_lock(&f->frame_thread.td.lock);
f->frame_thread.die = 1;
pthread_cond_signal(&f->frame_thread.td.cond);
@@ -439,11 +450,14 @@
pthread_mutex_destroy(&f->frame_thread.td.lock);
pthread_cond_destroy(&f->frame_thread.td.cond);
}
- if (f->n_tc > 1) {
+ if (f->n_tc > 1 && f->tc && f->tile_thread.inited) {
pthread_mutex_lock(&f->tile_thread.lock);
for (int m = 0; m < f->n_tc; m++) {
Dav1dTileContext *const t = &f->tc[m];
t->tile_thread.die = 1;
+ // mark not created tile threads as available
+ if (!t->tile_thread.td.inited)
+ f->tile_thread.available |= 1<<m;
}
pthread_cond_broadcast(&f->tile_thread.cond);
while (f->tile_thread.available != ~0ULL >> (64 - f->n_tc))
@@ -452,7 +466,7 @@
pthread_mutex_unlock(&f->tile_thread.lock);
for (int m = 0; m < f->n_tc; m++) {
Dav1dTileContext *const t = &f->tc[m];
- if (f->n_tc > 1) {
+ if (f->n_tc > 1 && t->tile_thread.td.inited) {
pthread_join(t->tile_thread.td.thread, NULL);
pthread_mutex_destroy(&t->tile_thread.td.lock);
pthread_cond_destroy(&t->tile_thread.td.cond);
@@ -463,13 +477,13 @@
pthread_cond_destroy(&f->tile_thread.icond);
freep(&f->tile_thread.task_idx_to_sby_and_tile_idx);
}
- for (int m = 0; m < f->n_tc; m++) {
+ for (int m = 0; f->tc && m < f->n_tc; m++) {
Dav1dTileContext *const t = &f->tc[m];
dav1d_free_aligned(t->cf);
dav1d_free_aligned(t->scratch.mem);
dav1d_free_aligned(t->emu_edge);
}
- for (int m = 0; m < f->n_ts; m++) {
+ for (int m = 0; f->ts && m < f->n_ts; m++) {
Dav1dTileState *const ts = &f->ts[m];
pthread_cond_destroy(&ts->tile_thread.cond);
pthread_mutex_destroy(&ts->tile_thread.lock);
@@ -483,13 +497,13 @@
free(f->lf.lr_mask);
free(f->lf.level);
free(f->lf.tx_lpf_right_edge[0]);
- av1_free_ref_mv_common(f->libaom_cm);
+ if (f->libaom_cm) av1_free_ref_mv_common(f->libaom_cm);
dav1d_free_aligned(f->lf.cdef_line);
dav1d_free_aligned(f->lf.lr_lpf_line);
}
dav1d_free_aligned(c->fc);
dav1d_data_unref_internal(&c->in);
- if (c->n_fc > 1) {
+ if (c->n_fc > 1 && c->frame_thread.out_delayed) {
for (unsigned n = 0; n < c->n_fc; n++)
if (c->frame_thread.out_delayed[n].p.data[0])
dav1d_thread_picture_unref(&c->frame_thread.out_delayed[n]);
--- a/src/thread_data.h
+++ b/src/thread_data.h
@@ -34,6 +34,7 @@
pthread_t thread;
pthread_cond_t cond;
pthread_mutex_t lock;
+ int inited;
};
#endif /* __DAV1D_SRC_THREAD_DATA_H__ */