]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
capmt/pmt parser: call caid_change callback outside s_stream_mutex (clang sanitizer)
authorJaroslav Kysela <perex@perex.cz>
Thu, 10 Mar 2016 17:15:04 +0000 (18:15 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 10 Mar 2016 17:15:04 +0000 (18:15 +0100)
src/descrambler/capmt.c
src/input/mpegts/dvb_psi.c

index a4fabfcc63bba207fec1acaf300419b34b622f2c..2d1466dafe996b28f62d47f11b9d0ec807a8c4d4 100644 (file)
@@ -1859,17 +1859,14 @@ capmt_caid_change(th_descrambler_t *td)
 {
   capmt_service_t *ct = (capmt_service_t *)td;
   capmt_t *capmt = ct->ct_capmt;
-  mpegts_service_t *t;
+  mpegts_service_t *t = (mpegts_service_t*)td->td_service;
   elementary_stream_t *st;
   capmt_caid_ecm_t *cce;
   caid_t *c;
   int change = 0;
 
   pthread_mutex_lock(&capmt->capmt_mutex);
-
-  t = (mpegts_service_t*)td->td_service;
-
-  lock_assert(&t->s_stream_mutex);
+  pthread_mutex_lock(&t->s_stream_mutex);
 
   TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) {
     if (t->s_dvb_prefcapid_lock == PREFCAPID_FORCE &&
@@ -1888,6 +1885,7 @@ capmt_caid_change(th_descrambler_t *td)
     }
   }
 
+  pthread_mutex_unlock(&t->s_stream_mutex);
   pthread_mutex_unlock(&capmt->capmt_mutex);
 
   if (change)
index 1531a151d6cf38e26be8faf35c6f77dd62f31754..19f91b02bd142530dce450a80170250de7ba6943 100644 (file)
@@ -88,7 +88,8 @@ typedef struct dvb_bat {
 int dvb_bouquets_parse = 1;
 
 static int
-psi_parse_pmt(mpegts_mux_t *mux, mpegts_service_t *t, const uint8_t *ptr, int len);
+psi_parse_pmt(mpegts_mux_t *mux, mpegts_service_t *t,
+              const uint8_t *ptr, int len, int *_update);
 
 static inline int
 mpegts_mux_alive(mpegts_mux_t *mm)
@@ -965,11 +966,27 @@ dvb_cat_callback
  * PMT processing
  */
 
+/* PMT update reason flags */
+#define PMT_UPDATE_PCR                0x1
+#define PMT_UPDATE_NEW_STREAM         0x2
+#define PMT_UPDATE_LANGUAGE           0x4
+#define PMT_UPDATE_AUDIO_TYPE         0x8
+#define PMT_UPDATE_FRAME_DURATION     0x10
+#define PMT_UPDATE_COMPOSITION_ID     0x20
+#define PMT_UPDATE_ANCILLARY_ID       0x40
+#define PMT_UPDATE_STREAM_DELETED     0x80
+#define PMT_UPDATE_NEW_CA_STREAM      0x100
+#define PMT_UPDATE_NEW_CAID           0x200
+#define PMT_UPDATE_CA_PROVIDER_CHANGE 0x400
+#define PMT_UPDATE_PARENT_PID         0x800
+#define PMT_UPDATE_CAID_DELETED       0x1000
+#define PMT_REORDERED                 0x2000
+
 int
 dvb_pmt_callback
   (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid)
 {
-  int r, sect, last, ver;
+  int r, sect, last, ver, update;
   uint16_t sid;
   mpegts_mux_t *mm = mt->mt_mux;
   mpegts_service_t *s;
@@ -988,9 +1005,12 @@ dvb_pmt_callback
 
   /* Process */
   tvhdebug("pmt", "sid %04X (%d)", sid, sid);
+  update = 0;
   pthread_mutex_lock(&s->s_stream_mutex);
-  r = psi_parse_pmt(mt->mt_mux, s, ptr, len);
+  r = psi_parse_pmt(mt->mt_mux, s, ptr, len, &update);
   pthread_mutex_unlock(&s->s_stream_mutex);
+  if (update & PMT_UPDATE_NEW_CAID)
+    descrambler_caid_changed((service_t *)s);
   if (r)
     service_restart((service_t*)s);
 
@@ -1959,24 +1979,6 @@ dvb_fs_sdt_callback
 }
 #endif
 
-/**
- * PMT update reason flags
- */
-#define PMT_UPDATE_PCR                0x1
-#define PMT_UPDATE_NEW_STREAM         0x2
-#define PMT_UPDATE_LANGUAGE           0x4
-#define PMT_UPDATE_AUDIO_TYPE         0x8
-#define PMT_UPDATE_FRAME_DURATION     0x10
-#define PMT_UPDATE_COMPOSITION_ID     0x20
-#define PMT_UPDATE_ANCILLARY_ID       0x40
-#define PMT_UPDATE_STREAM_DELETED     0x80
-#define PMT_UPDATE_NEW_CA_STREAM      0x100
-#define PMT_UPDATE_NEW_CAID           0x200
-#define PMT_UPDATE_CA_PROVIDER_CHANGE 0x400
-#define PMT_UPDATE_PARENT_PID         0x800
-#define PMT_UPDATE_CAID_DELETED       0x1000
-#define PMT_REORDERED                 0x2000
-
 /**
  * Add a CA descriptor
  */
@@ -2136,7 +2138,7 @@ psi_desc_teletext(mpegts_service_t *t, const uint8_t *ptr, int size,
  */
 static int
 psi_parse_pmt
-  (mpegts_mux_t *mux, mpegts_service_t *t, const uint8_t *ptr, int len)
+  (mpegts_mux_t *mux, mpegts_service_t *t, const uint8_t *ptr, int len, int *_update)
 {
   int ret = 0;
   uint16_t pcr_pid, pid;
@@ -2432,15 +2434,12 @@ psi_parse_pmt
       if(t->s_status == SERVICE_RUNNING)
         ret = 1;
     }
-    
-    // notify descrambler that we found another CAIDs
-    if (update & PMT_UPDATE_NEW_CAID)
-      descrambler_caid_changed((service_t *)t);
   }
 
   if (service_has_audio_or_video((service_t *)t))
     dvb_service_autoenable(t, "PAT and PMT");
 
+  *_update = update;
   return ret;
 }