]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
linuxdvb & satip: fix pid subscription locking
authorJaroslav Kysela <perex@perex.cz>
Fri, 1 May 2015 20:03:53 +0000 (22:03 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 1 May 2015 20:03:53 +0000 (22:03 +0200)
src/input/mpegts/linuxdvb/linuxdvb_frontend.c
src/input/mpegts/satip/satip_frontend.c

index f7756ba7f513329cd6fef5724b551b4a9db3c8c4..d1afb90e0947cee30131d9263e820b79d6563b2c 100644 (file)
@@ -366,19 +366,22 @@ static mpegts_pid_t *
 linuxdvb_frontend_open_pid
   ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner )
 {
-  mpegts_pid_t *mp;
   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
-  int change = 0;
+  mpegts_pid_t *mp;
+  int change;
+
+  if (!(mp = mpegts_input_open_pid(mi, mm, pid, type, weight, owner)))
+    return NULL;
 
+  change = 0;
+  pthread_mutex_lock(&lfe->lfe_dvr_lock);
   if (pid < MPEGTS_FULLMUX_PID)
     change = mpegts_pid_add(&lfe->lfe_pids, pid, weight) >= 0;
   else if (pid == MPEGTS_FULLMUX_PID) {
     change = lfe->lfe_pids.all == 0;
     lfe->lfe_pids.all = 1;
   }
-
-  if (!(mp = mpegts_input_open_pid(mi, mm, pid, type, weight, owner)))
-    return NULL;
+  pthread_mutex_unlock(&lfe->lfe_dvr_lock);
 
   if (change && lfe->lfe_dvr_pipe.wr > 0)
     tvh_write(lfe->lfe_dvr_pipe.wr, "c", 1);
@@ -391,17 +394,26 @@ linuxdvb_frontend_close_pid
   ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, void *owner )
 {
   linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
-  int change = 0, r;
+  mpegts_pid_t *mp;
+  mpegts_pid_sub_t *mps;
+  int change, r;
 
-  if (pid < MPEGTS_FULLMUX_PID)
-    change = mpegts_pid_del(&lfe->lfe_pids, pid, weight) >= 0;
-  else if (pid == MPEGTS_FULLMUX_PID) {
+  if ((r = mpegts_input_close_pid(mi, mm, pid, type, weight, owner)) <= 0)
+    return r;
+
+  change = 0;
+  pthread_mutex_lock(&lfe->lfe_dvr_lock);
+  if (pid == MPEGTS_FULLMUX_PID) {
     change = lfe->lfe_pids.all != 0;
     lfe->lfe_pids.all = 0;
+  } else if (pid < MPEGTS_FULLMUX_PID) {
+    mpegts_pid_done(&lfe->lfe_pids);
+    RB_FOREACH(mp, &mm->mm_pids, mp_link)
+      RB_FOREACH(mps, &mp->mp_subs, mps_link)
+        mpegts_pid_add(&lfe->lfe_pids, mp->mp_pid, mps->mps_weight);
+    change = 1;
   }
-
-  if ((r = mpegts_input_close_pid(mi, mm, pid, type, weight, owner)) <= 0)
-    return r;
+  pthread_mutex_unlock(&lfe->lfe_dvr_lock);
 
   if (change)
     tvh_write(lfe->lfe_dvr_pipe.wr, "c", 1);
index 9d4d2d3c81c82c17287ecb1801c0da59b1fc2af0..7a52c62e4b2f6bc4f8324b8b4f1091ed42e5a2f9 100644 (file)
@@ -561,7 +561,7 @@ satip_frontend_open_pid
   if (mp->mp_pid > MPEGTS_FULLMUX_PID)
     return mp;
 
-  pthread_mutex_unlock(&lfe->sf_dvr_lock);
+  pthread_mutex_lock(&lfe->sf_dvr_lock);
   if ((tr = lfe->sf_req) != NULL) {
     if (pid == MPEGTS_FULLMUX_PID) {
       if (lfe->sf_device->sd_fullmux_ok) {
@@ -580,10 +580,10 @@ satip_frontend_open_pid
     } else {
       change |= satip_frontend_add_pid(lfe, mp->mp_pid, weight);
     }
-    if (change)
-      tvh_write(lfe->sf_dvr_pipe.wr, "c", 1);
   }
   pthread_mutex_unlock(&lfe->sf_dvr_lock);
+  if (change)
+    tvh_write(lfe->sf_dvr_pipe.wr, "c", 1);
 
   return mp;
 }
@@ -594,15 +594,10 @@ satip_frontend_close_pid
 {
   satip_frontend_t *lfe = (satip_frontend_t*)mi;
   satip_tune_req_t *tr;
+  mpegts_pid_t *mp;
+  mpegts_pid_sub_t *mps;
   int change = 0, r;
 
-  if (pid < MPEGTS_FULLMUX_PID) {
-    pthread_mutex_lock(&lfe->sf_dvr_lock);
-    if ((tr = lfe->sf_req) != NULL)
-      change = mpegts_pid_del(&tr->sf_pids, pid, weight) >= 0;
-    pthread_mutex_unlock(&lfe->sf_dvr_lock);
-  }
-
   if ((r = mpegts_input_close_pid(mi, mm, pid, type, weight, owner)) <= 0)
     return r; /* return here even if change is nonzero - multiple PID subscribers */
 
@@ -620,6 +615,12 @@ satip_frontend_close_pid
           change = 1;
         }
       }
+    } else {
+      mpegts_pid_done(&tr->sf_pids);
+      RB_FOREACH(mp, &mm->mm_pids, mp_link)
+        RB_FOREACH(mps, &mp->mp_subs, mps_link)
+          mpegts_pid_add(&tr->sf_pids, mp->mp_pid, mps->mps_weight);
+      change = 1;
     }
     if (change)
       tvh_write(lfe->sf_dvr_pipe.wr, "c", 1);