mpegts tables: fix the deferred tables locking mechanism
This commit is contained in:
parent
f72733ff08
commit
98473cd229
4 changed files with 63 additions and 50 deletions
|
@ -179,7 +179,9 @@ struct mpegts_table
|
|||
uint8_t mt_finished;
|
||||
uint8_t mt_subscribed;
|
||||
uint8_t mt_defer_cmd;
|
||||
uint8_t mt_defer_reg;
|
||||
|
||||
#define MT_DEFER_OPEN_PID 1
|
||||
#define MT_DEFER_CLOSE_PID 2
|
||||
|
||||
int mt_count;
|
||||
|
||||
|
@ -769,6 +771,8 @@ static inline void mpegts_table_release
|
|||
assert(mt->mt_refcount > 0);
|
||||
if(--mt->mt_refcount == 0) mpegts_table_release_(mt);
|
||||
}
|
||||
int mpegts_table_type
|
||||
( mpegts_table_t *mt );
|
||||
mpegts_table_t *mpegts_table_add
|
||||
(mpegts_mux_t *mm, int tableid, int mask,
|
||||
mpegts_table_callback_t callback, void *opaque,
|
||||
|
|
|
@ -590,37 +590,23 @@ static void
|
|||
mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm )
|
||||
{
|
||||
mpegts_table_t *mt;
|
||||
int type;
|
||||
|
||||
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)
|
||||
continue;
|
||||
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 (mt->mt_defer_cmd == 1) {
|
||||
if (mt->mt_defer_cmd == MT_DEFER_OPEN_PID && !mt->mt_destroyed) {
|
||||
mt->mt_defer_cmd = 0;
|
||||
mt->mt_defer_reg = 1;
|
||||
LIST_INSERT_HEAD(&mm->mm_tables, mt, mt_link);
|
||||
mm->mm_num_tables++;
|
||||
if (!mt->mt_subscribed) {
|
||||
mt->mt_subscribed = 1;
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
mi->mi_open_pid(mi, mm, mt->mt_pid, type, mt);
|
||||
mi->mi_open_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt);
|
||||
}
|
||||
} else if (mt->mt_defer_cmd == 2) {
|
||||
} else if (mt->mt_defer_cmd == MT_DEFER_CLOSE_PID) {
|
||||
mt->mt_defer_cmd = 0;
|
||||
mt->mt_defer_reg = 0;
|
||||
LIST_REMOVE(mt, mt_link);
|
||||
mm->mm_num_tables--;
|
||||
if (mt->mt_subscribed) {
|
||||
mt->mt_subscribed = 0;
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
mi->mi_close_pid(mi, mm, mt->mt_pid, type, mt);
|
||||
mi->mi_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt);
|
||||
}
|
||||
} else {
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
|
|
|
@ -708,13 +708,12 @@ void
|
|||
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;
|
||||
pthread_mutex_lock(&mm->mm_tables_lock);
|
||||
if (mt->mt_destroyed) {
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
return;
|
||||
}
|
||||
if (!mm->mm_active || !mm->mm_active->mmi_input) {
|
||||
mt->mt_subscribed = 0;
|
||||
LIST_INSERT_HEAD(&mm->mm_tables, mt, mt_link);
|
||||
|
@ -723,12 +722,14 @@ mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe )
|
|||
return;
|
||||
}
|
||||
if (mt->mt_flags & MT_DEFER) {
|
||||
if (mt->mt_defer_reg || mt->mt_defer_cmd == 1) {
|
||||
if (mt->mt_defer_cmd == MT_DEFER_OPEN_PID) {
|
||||
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_tables, mt, mt_link);
|
||||
mm->mm_num_tables++;
|
||||
mt->mt_defer_cmd = MT_DEFER_OPEN_PID;
|
||||
LIST_INSERT_HEAD(&mm->mm_defer_tables, mt, mt_defer_link);
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
return;
|
||||
|
@ -739,7 +740,7 @@ mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe )
|
|||
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);
|
||||
mi->mi_open_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt);
|
||||
mt->mt_subscribed = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&mi->mi_output_lock);
|
||||
|
@ -749,14 +750,13 @@ void
|
|||
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;
|
||||
pthread_mutex_lock(&mm->mm_tables_lock);
|
||||
if (!mm->mm_active || !mm->mm_active->mmi_input) {
|
||||
if (mt->mt_defer_cmd) {
|
||||
LIST_REMOVE(mt, mt_defer_link);
|
||||
mt->mt_defer_cmd = 0;
|
||||
}
|
||||
mt->mt_subscribed = 0;
|
||||
LIST_REMOVE(mt, mt_link);
|
||||
mm->mm_num_tables--;
|
||||
|
@ -764,23 +764,21 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
|
|||
return;
|
||||
}
|
||||
if (mt->mt_flags & MT_DEFER) {
|
||||
if (mt->mt_defer_cmd == 2) {
|
||||
if (mt->mt_defer_cmd == MT_DEFER_CLOSE_PID) {
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
return;
|
||||
}
|
||||
if (mt->mt_defer_cmd == 1) {
|
||||
if (mt->mt_defer_cmd == MT_DEFER_OPEN_PID) {
|
||||
LIST_REMOVE(mt, mt_defer_link);
|
||||
mt->mt_defer_cmd = 0;
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
mpegts_table_release(mt);
|
||||
return;
|
||||
}
|
||||
if (!mt->mt_defer_reg) {
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
return;
|
||||
}
|
||||
mpegts_table_grab(mt); /* thread will release the table */
|
||||
mt->mt_defer_cmd = 2;
|
||||
mpegts_table_grab(mt); /* thread will free the table */
|
||||
LIST_REMOVE(mt, mt_link);
|
||||
mm->mm_num_tables--;
|
||||
mt->mt_defer_cmd = MT_DEFER_CLOSE_PID;
|
||||
LIST_INSERT_HEAD(&mm->mm_defer_tables, mt, mt_defer_link);
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
return;
|
||||
|
@ -791,7 +789,7 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
|
|||
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);
|
||||
mi->mi_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt);
|
||||
mt->mt_subscribed = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&mi->mi_output_lock);
|
||||
|
|
|
@ -126,6 +126,19 @@ mpegts_table_destroy ( mpegts_table_t *mt )
|
|||
mpegts_table_release(mt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine table type
|
||||
*/
|
||||
int
|
||||
mpegts_table_type ( mpegts_table_t *mt )
|
||||
{
|
||||
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;
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new DVB table
|
||||
|
@ -206,26 +219,38 @@ void
|
|||
mpegts_table_flush_all ( mpegts_mux_t *mm )
|
||||
{
|
||||
mpegts_table_t *mt;
|
||||
mpegts_input_t *mi;
|
||||
|
||||
descrambler_flush_tables(mm);
|
||||
mi = mm->mm_active ? mm->mm_active->mmi_input : NULL;
|
||||
pthread_mutex_lock(&mm->mm_tables_lock);
|
||||
while ((mt = LIST_FIRST(&mm->mm_defer_tables))) {
|
||||
LIST_REMOVE(mt, mt_defer_link);
|
||||
if (!mt->mt_defer_reg) {
|
||||
/* registration not fished, but ... */
|
||||
/* allow the table free in next table destroy loop */
|
||||
mt->mt_defer_reg = 1;
|
||||
LIST_INSERT_HEAD(&mm->mm_tables, mt, mt_link);
|
||||
mm->mm_num_tables++;
|
||||
if (mt->mt_defer_cmd == MT_DEFER_CLOSE_PID) {
|
||||
if (mi) {
|
||||
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, mpegts_table_type(mt), mt);
|
||||
mt->mt_subscribed = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&mi->mi_output_lock);
|
||||
pthread_mutex_lock(&mm->mm_tables_lock);
|
||||
} else{
|
||||
mt->mt_subscribed = 0;
|
||||
}
|
||||
}
|
||||
mt->mt_defer_cmd = 0;
|
||||
mpegts_table_release(mt);
|
||||
}
|
||||
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 */
|
||||
mt->mt_flags &= ~MT_DEFER; /* force destroy */
|
||||
mt->mt_destroyed = 1; /* early destroy mark */
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
mpegts_table_destroy(mt);
|
||||
pthread_mutex_lock(&mm->mm_tables_lock);
|
||||
}
|
||||
pthread_mutex_unlock(&mm->mm_tables_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Reference in a new issue