]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
mpegts: tables - fix the assert() in the table dispatch routine
authorJaroslav Kysela <perex@perex.cz>
Fri, 11 Jul 2014 14:13:20 +0000 (16:13 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 11 Jul 2014 14:15:18 +0000 (16:15 +0200)
- 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
src/input/mpegts/mpegts_input.c
src/input/mpegts/mpegts_mux.c
src/input/mpegts/mpegts_table.c

index 386f255f61e457f8cb90254807d2b80144855036..bd7eec405c513b751f4f0abfca37a252cab4b9da 100644 (file)
@@ -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;
index 4ef4268fa331ce744d36a7943f1339bc1523ed02..b928f6e4a34c1c7ca8d7b1172df3cf54faaeab54 100644 (file)
@@ -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
index 58094cee86f7e4d95944b99631bd1967f11f6c14..c550882b7f583773bd354e6a2d06136cb79ec265 100644 (file)
@@ -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);
index 5032a0de4c33cb5532daa63081f6844199cda5e7..c3b6f7bbcf7d982c337b6dcc148cb188b95c1138 100644 (file)
@@ -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 */