]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
mpegts tables: added mpegts_table_consistency_check to invoke psi tables inconsistenc... 509/head
authorJaroslav Kysela <perex@perex.cz>
Mon, 20 Oct 2014 18:35:15 +0000 (20:35 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 20 Oct 2014 18:35:15 +0000 (20:35 +0200)
src/input/mpegts.h
src/input/mpegts/mpegts_input.c
src/input/mpegts/mpegts_mux.c
src/input/mpegts/mpegts_table.c

index acbf49db2238a7a3ab5f66d0245447707bd26de6..ac49c844deb0f826502323f94746ce64090399d0 100644 (file)
@@ -802,6 +802,8 @@ void mpegts_table_flush_all
   (mpegts_mux_t *mm);
 void mpegts_table_destroy ( mpegts_table_t *mt );
 
+void mpegts_table_consistency_check( mpegts_mux_t *mm );
+
 mpegts_service_t *mpegts_service_create0
   ( mpegts_service_t *ms, const idclass_t *class, const char *uuid,
     mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, htsmsg_t *conf );
index c6ef152e2abb2574b368d6f7ae9fe25e18109e47..c5aef130016e2f21ce993b912cdfc4101ffb9170 100644 (file)
@@ -655,6 +655,7 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm )
 
   pthread_mutex_lock(&mm->mm_tables_lock);
   while ((mt = TAILQ_FIRST(&mm->mm_defer_tables)) != NULL) {
+    mpegts_table_consistency_check(mm);
     TAILQ_REMOVE(&mm->mm_defer_tables, mt, mt_defer_link);
     if (mt->mt_defer_cmd == MT_DEFER_OPEN_PID && !mt->mt_destroyed) {
       mt->mt_defer_cmd = 0;
@@ -680,6 +681,7 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm )
     mpegts_table_release(mt);
     pthread_mutex_lock(&mm->mm_tables_lock);
   }
+  mpegts_table_consistency_check(mm);
   pthread_mutex_unlock(&mm->mm_tables_lock);
 }
 
@@ -925,8 +927,7 @@ mpegts_input_flush_mux
   }
   pthread_mutex_unlock(&mi->mi_input_lock);
 
-  /* Flush table Q */
-  pthread_mutex_lock(&mi->mi_output_lock);
+  /* Flush table Q - the global lock is already held */
   TAILQ_FOREACH(mtf, &mi->mi_table_queue, mtf_link) {
     if (mtf->mtf_mux == mm)
       mtf->mtf_mux = NULL;
@@ -935,7 +936,6 @@ mpegts_input_flush_mux
                                    (mi->mi_destroyed_muxes_count + 1) *
                                      sizeof(mpegts_mux_t *));
   mi->mi_destroyed_muxes[mi->mi_destroyed_muxes_count++] = mm;
-  pthread_mutex_unlock(&mi->mi_output_lock);
 }
 
 static void
index 69c2cc6be06da4698e50ba55fc9060c443602ea6..3712394741e9fcaf943d0b163a5293a683c6e138 100644 (file)
@@ -838,6 +838,7 @@ mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res )
 
   /* Log */
   pthread_mutex_lock(&mm->mm_tables_lock);
+  mpegts_table_consistency_check(mm);
   LIST_FOREACH(mt, &mm->mm_tables, mt_link) {
     if (mt->mt_flags & MT_QUICKREQ) {
       const char *s = "not found";
@@ -862,7 +863,7 @@ mpegts_mux_scan_timeout ( void *aux )
   int c, q;
   char buf[256];
   mpegts_mux_t *mm = aux;
-  mpegts_table_t *mt, *nxt;
+  mpegts_table_t *mt;
   mpegts_mux_nice_name(mm, buf, sizeof(buf));
 
   /* Timeout */
@@ -876,13 +877,15 @@ mpegts_mux_scan_timeout ( void *aux )
   /* Check tables */
 again:
   pthread_mutex_lock(&mm->mm_tables_lock);
+  mpegts_table_consistency_check(mm);
   c = q = 0;
-  for (mt = LIST_FIRST(&mm->mm_tables); mt != NULL; mt = nxt) {
-    nxt = LIST_NEXT(mt, mt_link);
+  LIST_FOREACH(mt, &mm->mm_tables, mt_link) {
     if (!(mt->mt_flags & MT_QUICKREQ)) continue;
     if (!mt->mt_count) {
+      mpegts_table_grab(mt);
       pthread_mutex_unlock(&mm->mm_tables_lock);
       mpegts_table_destroy(mt);
+      mpegts_table_release(mt);
       goto again;
     } else if (!mt->mt_complete) {
       q++;
index e7dedb37b8ffc6ffbfeee034f556d09f06f9855d..3b504edd4b394b501eb57dffbe62514be88d7688 100644 (file)
 
 #include <assert.h>
 
+void
+mpegts_table_consistency_check ( mpegts_mux_t *mm )
+{
+#if ENABLE_TRACE
+  int i, c = 0;
+  mpegts_table_t *mt;
+
+  lock_assert(&mm->mm_tables_lock);
+
+  i = mm->mm_num_tables;
+  LIST_FOREACH(mt, &mm->mm_tables, mt_link)
+    c++;
+
+  if (i != c) {
+    tvherror("mpegts", "tables count inconsistency (num %d, list %d)", i, c);
+    abort();
+  }
+#endif
+}
+
 static void
 mpegts_table_fastswitch ( mpegts_mux_t *mm )
 {
@@ -131,8 +151,10 @@ mpegts_table_destroy ( mpegts_table_t *mt )
   mpegts_mux_t *mm = mt->mt_mux;
 
   pthread_mutex_lock(&mm->mm_tables_lock);
+  mpegts_table_consistency_check(mm);
   mt->mt_destroyed = 1;
   mt->mt_mux->mm_close_table(mt->mt_mux, mt);
+  mpegts_table_consistency_check(mm);
   pthread_mutex_unlock(&mm->mm_tables_lock);
   mpegts_table_release(mt);
 }
@@ -165,6 +187,7 @@ mpegts_table_add
 
   /* Check for existing */
   pthread_mutex_lock(&mm->mm_tables_lock);
+  mpegts_table_consistency_check(mm);
   LIST_FOREACH(mt, &mm->mm_tables, mt_link) {
     if (mt->mt_opaque != opaque)
       continue;
@@ -186,6 +209,7 @@ mpegts_table_add
       if (!(flags & MT_SKIPSUBS) && !mt->mt_subscribed)
         mm->mm_open_table(mm, mt, 1);
     }
+    mpegts_table_consistency_check(mm);
     pthread_mutex_unlock(&mm->mm_tables_lock);
     return mt;
   }
@@ -215,6 +239,7 @@ mpegts_table_add
       subscribe = 0;
   }
   mm->mm_open_table(mm, mt, subscribe);
+  mpegts_table_consistency_check(mm);
   pthread_mutex_unlock(&mm->mm_tables_lock);
   return mt;
 }
@@ -229,6 +254,7 @@ mpegts_table_flush_all ( mpegts_mux_t *mm )
 
   descrambler_flush_tables(mm);
   pthread_mutex_lock(&mm->mm_tables_lock);
+  mpegts_table_consistency_check(mm);
   while ((mt = TAILQ_FIRST(&mm->mm_defer_tables))) {
     TAILQ_REMOVE(&mm->mm_defer_tables, mt, mt_defer_link);
     mt->mt_defer_cmd = 0;
@@ -237,10 +263,17 @@ mpegts_table_flush_all ( mpegts_mux_t *mm )
   while ((mt = LIST_FIRST(&mm->mm_tables))) {
     mt->mt_flags &= ~MT_DEFER; /* force destroy */
     mt->mt_destroyed = 1;      /* early destroy mark */
+    mpegts_table_grab(mt);
+    mpegts_table_consistency_check(mm);
     pthread_mutex_unlock(&mm->mm_tables_lock);
     mpegts_table_destroy(mt);
+    mpegts_table_release(mt);
     pthread_mutex_lock(&mm->mm_tables_lock);
+    mpegts_table_consistency_check(mm);
   }
+  assert(mm->mm_num_tables == 0);
+  assert(TAILQ_FIRST(&mm->mm_defer_tables) == NULL);
+  assert(LIST_FIRST(&mm->mm_tables) == NULL);
   pthread_mutex_unlock(&mm->mm_tables_lock);
 }