mpegts: fix the table locking
The table must be inserted/removed in the mi_output_lock protection, because mpegts_input_table_dispatch() requires the consistent list and the count of tables (see assert).
This commit is contained in:
parent
cd428fb040
commit
1a19efd3bd
3 changed files with 35 additions and 24 deletions
|
@ -374,7 +374,7 @@ struct mpegts_mux
|
|||
int (*mm_is_enabled) (mpegts_mux_t *mm);
|
||||
int (*mm_start) (mpegts_mux_t *mm, const char *r, int w);
|
||||
void (*mm_stop) (mpegts_mux_t *mm, int force);
|
||||
void (*mm_open_table) (mpegts_mux_t*,mpegts_table_t*);
|
||||
void (*mm_open_table) (mpegts_mux_t*,mpegts_table_t*,int subscribe);
|
||||
void (*mm_close_table) (mpegts_mux_t*,mpegts_table_t*);
|
||||
void (*mm_create_instances) (mpegts_mux_t*);
|
||||
|
||||
|
@ -688,7 +688,7 @@ int mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force );
|
|||
int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid );
|
||||
int mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth );
|
||||
|
||||
void mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt );
|
||||
void mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe );
|
||||
void mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt );
|
||||
|
||||
void mpegts_mux_remove_subscriber(mpegts_mux_t *mm, th_subscription_t *s, int reason);
|
||||
|
|
|
@ -673,18 +673,29 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force )
|
|||
}
|
||||
|
||||
void
|
||||
mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
|
||||
mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe )
|
||||
{
|
||||
mpegts_input_t *mi;
|
||||
int type = 0;
|
||||
|
||||
if (mt->mt_flags & MT_FAST) type |= MPS_FTABLE;
|
||||
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;
|
||||
mpegts_input_t *mi;
|
||||
if (!mm->mm_active || !mm->mm_active->mmi_input) return;
|
||||
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++;
|
||||
return;
|
||||
}
|
||||
mi = mm->mm_active->mmi_input;
|
||||
pthread_mutex_lock(&mi->mi_output_lock);
|
||||
mi->mi_open_pid(mi, mm, mt->mt_pid, type, mt);
|
||||
LIST_INSERT_HEAD(&mm->mm_tables, mt, mt_link);
|
||||
mm->mm_num_tables++;
|
||||
if (subscribe) {
|
||||
mi->mi_open_pid(mi, mm, mt->mt_pid, type, mt);
|
||||
mt->mt_subscribed = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&mi->mi_output_lock);
|
||||
}
|
||||
|
||||
|
@ -693,14 +704,25 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
|
|||
{
|
||||
mpegts_input_t *mi;
|
||||
int type = 0;
|
||||
|
||||
if (mt->mt_flags & MT_FAST) type |= MPS_FTABLE;
|
||||
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;
|
||||
if (!mm->mm_active || !mm->mm_active->mmi_input) return;
|
||||
if (!mm->mm_active || !mm->mm_active->mmi_input) {
|
||||
mt->mt_subscribed = 0;
|
||||
LIST_REMOVE(mt, mt_link);
|
||||
mm->mm_num_tables--;
|
||||
return;
|
||||
}
|
||||
mi = mm->mm_active->mmi_input;
|
||||
pthread_mutex_lock(&mi->mi_output_lock);
|
||||
mi->mi_close_pid(mi, mm, mt->mt_pid, type, mt);
|
||||
LIST_REMOVE(mt, mt_link);
|
||||
mm->mm_num_tables--;
|
||||
if (mt->mt_subscribed) {
|
||||
mi->mi_close_pid(mi, mm, mt->mt_pid, type, mt);
|
||||
mt->mt_subscribed = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&mi->mi_output_lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -104,11 +104,8 @@ void
|
|||
mpegts_table_destroy ( mpegts_table_t *mt )
|
||||
{
|
||||
struct mpegts_table_state *st;
|
||||
LIST_REMOVE(mt, mt_link);
|
||||
mt->mt_destroyed = 1;
|
||||
mt->mt_mux->mm_num_tables--;
|
||||
if (mt->mt_subscribed)
|
||||
mt->mt_mux->mm_close_table(mt->mt_mux, mt);
|
||||
mt->mt_mux->mm_close_table(mt->mt_mux, mt);
|
||||
while ((st = RB_FIRST(&mt->mt_state))) {
|
||||
RB_REMOVE(&mt->mt_state, st, link);
|
||||
free(st);
|
||||
|
@ -141,8 +138,7 @@ mpegts_table_add
|
|||
mt->mt_callback = callback;
|
||||
mt->mt_pid = pid;
|
||||
mt->mt_table = tableid;
|
||||
mt->mt_subscribed = 1;
|
||||
mm->mm_open_table(mm, mt);
|
||||
mm->mm_open_table(mm, mt, 1);
|
||||
} else if (pid >= 0) {
|
||||
if (mt->mt_pid != pid)
|
||||
continue;
|
||||
|
@ -151,10 +147,8 @@ mpegts_table_add
|
|||
} else {
|
||||
if (strcmp(mt->mt_name, name))
|
||||
continue;
|
||||
if (!(flags & MT_SKIPSUBS) && !mt->mt_subscribed) {
|
||||
mt->mt_subscribed = 1;
|
||||
mm->mm_open_table(mm, mt);
|
||||
}
|
||||
if (!(flags & MT_SKIPSUBS) && !mt->mt_subscribed)
|
||||
mm->mm_open_table(mm, mt, 1);
|
||||
}
|
||||
return mt;
|
||||
}
|
||||
|
@ -174,8 +168,6 @@ mpegts_table_add
|
|||
mt->mt_mask = mask;
|
||||
mt->mt_mux = mm;
|
||||
mt->mt_cc = -1;
|
||||
LIST_INSERT_HEAD(&mm->mm_tables, mt, mt_link);
|
||||
mm->mm_num_tables++;
|
||||
|
||||
/* Open table */
|
||||
if (pid < 0) {
|
||||
|
@ -186,10 +178,7 @@ mpegts_table_add
|
|||
if (mm->mm_scan_state == MM_SCAN_STATE_IDLE)
|
||||
subscribe = 0;
|
||||
}
|
||||
if (subscribe) {
|
||||
mt->mt_subscribed = 1;
|
||||
mm->mm_open_table(mm, mt);
|
||||
}
|
||||
mm->mm_open_table(mm, mt, subscribe);
|
||||
return mt;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue