From 528a1db428bd3456dfcffe867f8397562191de56 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 11 Jul 2014 16:13:20 +0200 Subject: [PATCH] mpegts: tables - fix the assert() in the table dispatch routine - rename mm_defer_tables_lock to mm_tables_lock - protect all table list operations with this lock - use this lock in the table dispatch routine --- src/input/mpegts.h | 2 +- src/input/mpegts/mpegts_input.c | 20 ++++++++++++-------- src/input/mpegts/mpegts_mux.c | 26 +++++++++++++++----------- src/input/mpegts/mpegts_table.c | 4 ++-- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 386f255f..bd7eec40 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -377,7 +377,7 @@ struct mpegts_mux int mm_num_tables; LIST_HEAD(, mpegts_table) mm_tables; LIST_HEAD(, mpegts_table) mm_defer_tables; - pthread_mutex_t mm_defer_tables_lock; + pthread_mutex_t mm_tables_lock; TAILQ_HEAD(, mpegts_table) mm_table_queue; LIST_HEAD(, caid) mm_descrambler_caids; diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 4ef4268f..b928f6e4 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -543,16 +543,20 @@ static void mpegts_input_table_dispatch ( mpegts_mux_t *mm, const uint8_t *tsb ) { int i = 0; - int len = mm->mm_num_tables; + int len; uint16_t pid = ((tsb[1] & 0x1f) << 8) | tsb[2]; uint8_t cc = (tsb[3] & 0x0f); - mpegts_table_t *mt, *vec[len]; + mpegts_table_t *mt, **vec; /* Collate - tables may be removed during callbacks */ + pthread_mutex_lock(&mm->mm_tables_lock); + len = mm->mm_num_tables; + vec = alloca(len * sizeof(mpegts_table_t *)); LIST_FOREACH(mt, &mm->mm_tables, mt_link) { mpegts_table_grab(mt); vec[i++] = mt; } + pthread_mutex_unlock(&mm->mm_tables_lock); assert(i == len); /* Process */ @@ -582,7 +586,7 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm ) mpegts_table_t *mt; int type; - pthread_mutex_lock(&mm->mm_defer_tables_lock); + pthread_mutex_lock(&mm->mm_tables_lock); while ((mt = LIST_FIRST(&mm->mm_defer_tables)) != NULL) { LIST_REMOVE(mt, mt_defer_link); if (mt->mt_destroyed) @@ -599,7 +603,7 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm ) mm->mm_num_tables++; if (!mt->mt_subscribed) { mt->mt_subscribed = 1; - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); mi->mi_open_pid(mi, mm, mt->mt_pid, type, mt); } } else if (mt->mt_defer_cmd == 2) { @@ -609,16 +613,16 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm ) mm->mm_num_tables--; if (mt->mt_subscribed) { mt->mt_subscribed = 0; - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); mi->mi_close_pid(mi, mm, mt->mt_pid, type, mt); } } else { - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); } mpegts_table_release(mt); - pthread_mutex_lock(&mm->mm_defer_tables_lock); + pthread_mutex_lock(&mm->mm_tables_lock); } - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); } static void diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 58094cee..c550882b 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -714,28 +714,30 @@ mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe ) if (mt->mt_flags & MT_SLOW) type |= MPS_TABLE; if (mt->mt_flags & MT_RECORD) type |= MPS_STREAM; if ((type & (MPS_FTABLE | MPS_TABLE)) == 0) type |= MPS_TABLE; + pthread_mutex_lock(&mm->mm_tables_lock); if (!mm->mm_active || !mm->mm_active->mmi_input) { mt->mt_subscribed = 0; LIST_INSERT_HEAD(&mm->mm_tables, mt, mt_link); mm->mm_num_tables++; + pthread_mutex_unlock(&mm->mm_tables_lock); return; } if (mt->mt_flags & MT_DEFER) { - pthread_mutex_lock(&mm->mm_defer_tables_lock); if (mt->mt_defer_reg || mt->mt_defer_cmd == 1) { - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); return; } mpegts_table_grab(mt); /* thread will release the table */ mt->mt_defer_cmd = 1; LIST_INSERT_HEAD(&mm->mm_defer_tables, mt, mt_defer_link); - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); return; } mi = mm->mm_active->mmi_input; - pthread_mutex_lock(&mi->mi_output_lock); LIST_INSERT_HEAD(&mm->mm_tables, mt, mt_link); mm->mm_num_tables++; + pthread_mutex_unlock(&mm->mm_tables_lock); + pthread_mutex_lock(&mi->mi_output_lock); if (subscribe) { mi->mi_open_pid(mi, mm, mt->mt_pid, type, mt); mt->mt_subscribed = 1; @@ -753,39 +755,41 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) if (mt->mt_flags & MT_SLOW) type |= MPS_TABLE; if (mt->mt_flags & MT_RECORD) type |= MPS_STREAM; if ((type & (MPS_FTABLE | MPS_TABLE)) == 0) type |= MPS_TABLE; + pthread_mutex_lock(&mm->mm_tables_lock); if (!mm->mm_active || !mm->mm_active->mmi_input) { mt->mt_subscribed = 0; LIST_REMOVE(mt, mt_link); mm->mm_num_tables--; + pthread_mutex_unlock(&mm->mm_tables_lock); return; } if (mt->mt_flags & MT_DEFER) { - pthread_mutex_lock(&mm->mm_defer_tables_lock); if (mt->mt_defer_cmd == 2) { - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); return; } if (mt->mt_defer_cmd == 1) { LIST_REMOVE(mt, mt_defer_link); mt->mt_defer_cmd = 0; - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); mpegts_table_release(mt); return; } if (!mt->mt_defer_reg) { - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); return; } mpegts_table_grab(mt); /* thread will release the table */ mt->mt_defer_cmd = 2; LIST_INSERT_HEAD(&mm->mm_defer_tables, mt, mt_defer_link); - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); return; } mi = mm->mm_active->mmi_input; - pthread_mutex_lock(&mi->mi_output_lock); LIST_REMOVE(mt, mt_link); mm->mm_num_tables--; + pthread_mutex_unlock(&mm->mm_tables_lock); + pthread_mutex_lock(&mi->mi_output_lock); if (mt->mt_subscribed) { mi->mi_close_pid(mi, mm, mt->mt_pid, type, mt); mt->mt_subscribed = 0; @@ -911,7 +915,7 @@ mpegts_mux_create0 /* Table processing */ mm->mm_open_table = mpegts_mux_open_table; mm->mm_close_table = mpegts_mux_close_table; - pthread_mutex_init(&mm->mm_defer_tables_lock, NULL); + pthread_mutex_init(&mm->mm_tables_lock, NULL); TAILQ_INIT(&mm->mm_table_queue); LIST_INIT(&mm->mm_descrambler_caids); TAILQ_INIT(&mm->mm_descrambler_tables); diff --git a/src/input/mpegts/mpegts_table.c b/src/input/mpegts/mpegts_table.c index 5032a0de..c3b6f7bb 100644 --- a/src/input/mpegts/mpegts_table.c +++ b/src/input/mpegts/mpegts_table.c @@ -197,13 +197,13 @@ mpegts_table_flush_all ( mpegts_mux_t *mm ) { mpegts_table_t *mt; descrambler_flush_tables(mm); - pthread_mutex_lock(&mm->mm_defer_tables_lock); + pthread_mutex_lock(&mm->mm_tables_lock); while ((mt = LIST_FIRST(&mm->mm_defer_tables))) { LIST_REMOVE(mt, mt_defer_link); mt->mt_defer_cmd = 0; mpegts_table_release(mt); } - pthread_mutex_unlock(&mm->mm_defer_tables_lock); + pthread_mutex_unlock(&mm->mm_tables_lock); while ((mt = LIST_FIRST(&mm->mm_tables))) { if ((mt->mt_flags & MT_DEFER) && mt->mt_defer_reg) mt->mt_flags &= ~MT_DEFER; /* force destroy */