]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
SAT>IP: corner case fixes, fixes #2638
authorJaroslav Kysela <perex@perex.cz>
Sun, 25 Jan 2015 17:23:51 +0000 (18:23 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sun, 25 Jan 2015 17:25:30 +0000 (18:25 +0100)
- fixed wait before next tune (flush the incoming rtsp replies)
- fixed mutex global_lock deadlock (satip_frontend_tuning_error)

src/input/mpegts.h
src/input/mpegts/mpegts_mux.c
src/input/mpegts/satip/satip_frontend.c

index 707d9e146b66081db4f08128443802eacd725feb..ade18bcbb5f0f03f424efd77f67b269967e9c33f 100644 (file)
@@ -755,7 +755,7 @@ void mpegts_mux_delete ( mpegts_mux_t *mm, int delconf );
 
 void mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c );
 
-void mpegts_mux_tuning_error( mpegts_mux_t *mm );
+void mpegts_mux_tuning_error( const char *mux_uuid, mpegts_mux_instance_t *mmi_match );
 
 mpegts_mux_instance_t *mpegts_mux_instance_create0
   ( mpegts_mux_instance_t *mmi, const idclass_t *class, const char *uuid,
index 771eabde9006031b738326a5b33bb10b128bb45e..8087f1e40cf6687c59428a1fefdfda6fe494f7f9 100644 (file)
@@ -1314,21 +1314,30 @@ mpegts_mux_unsubscribe_by_name
 }
 
 void
-mpegts_mux_tuning_error ( mpegts_mux_t *mm )
+mpegts_mux_tuning_error ( const char *mux_uuid, mpegts_mux_instance_t *mmi_match )
 {
+  mpegts_mux_t *mm;
   th_subscription_t *sub;
   mpegts_mux_instance_t *mmi;
   streaming_message_t *sm;
-
-  lock_assert(&global_lock);
-
-  if ((mmi = mm->mm_active) != NULL) {
-    LIST_FOREACH(sub, &mmi->mmi_subs, ths_mmi_link) {
-      sm = streaming_msg_create_code(SMT_SERVICE_STATUS, TSS_TUNING);
-      streaming_target_deliver(sub->ths_output, sm);
+  struct timespec timeout;
+
+  timeout.tv_sec = 2;
+  timeout.tv_nsec = 0;
+
+  if (!pthread_mutex_timedlock(&global_lock, &timeout)) {
+    mm = mpegts_mux_find(mux_uuid);
+    if (mm) {
+      if ((mmi = mm->mm_active) != NULL && mmi == mmi_match) {
+        LIST_FOREACH(sub, &mmi->mmi_subs, ths_mmi_link) {
+          sm = streaming_msg_create_code(SMT_SERVICE_STATUS, TSS_TUNING);
+          streaming_target_deliver(sub->ths_output, sm);
+        }
+        if (mmi->mmi_input)
+          mmi->mmi_input->mi_tuning_error(mmi->mmi_input, mm);
+      }
     }
-    if (mmi->mmi_input)
-      mmi->mmi_input->mi_tuning_error(mmi->mmi_input, mm);
+    pthread_mutex_unlock(&global_lock);
   }
 }
 
index 95f5e6bb37bb3690d3c158fe28312719b55b5b70..c95adce40f8501bfefe7ba8ef9c941bd735870cf 100644 (file)
@@ -1116,13 +1116,43 @@ satip_frontend_shutdown ( http_client_t *rtsp, tvhpoll_t *efd )
 static void
 satip_frontend_tuning_error ( satip_frontend_t *lfe, satip_tune_req_t *tr )
 {
-  pthread_mutex_lock(&global_lock);
+  mpegts_mux_t *mm;
+  mpegts_mux_instance_t *mmi;
+  char uuid[UUID_HEX_SIZE];
+
   pthread_mutex_lock(&lfe->sf_dvr_lock);
   if (lfe->sf_running && lfe->sf_req == tr &&
-      tr->sf_mmi && tr->sf_mmi->mmi_mux)
-    mpegts_mux_tuning_error(tr->sf_mmi->mmi_mux);
+      (mmi = tr->sf_mmi) != NULL && (mm = mmi->mmi_mux) != NULL) {
+    strcpy(uuid, idnode_uuid_as_str(&mm->mm_id));
+    pthread_mutex_unlock(&lfe->sf_dvr_lock);
+    mpegts_mux_tuning_error(uuid, mmi);
+    return;
+  }
   pthread_mutex_unlock(&lfe->sf_dvr_lock);
-  pthread_mutex_unlock(&global_lock);
+}
+
+static void
+satip_frontend_close_rtsp
+  ( satip_frontend_t *lfe, tvhpoll_t *efd, http_client_t **rtsp )
+{
+  tvhpoll_event_t ev;
+
+  memset(&ev, 0, sizeof(ev));
+  ev.events   = TVHPOLL_IN;
+  ev.fd       = lfe->sf_dvr_pipe.rd;
+  ev.data.ptr = NULL;
+  tvhpoll_rem(efd, &ev, 1);
+
+  satip_frontend_shutdown(*rtsp, efd);
+
+  memset(&ev, 0, sizeof(ev));
+  ev.events   = TVHPOLL_IN;
+  ev.fd       = lfe->sf_dvr_pipe.rd;
+  ev.data.ptr = NULL;
+  tvhpoll_add(efd, &ev, 1);
+
+  http_client_close(*rtsp);
+  *rtsp = NULL;
 }
 
 static void *
@@ -1186,25 +1216,7 @@ new_tune:
     nfds = tvhpoll_wait(efd, ev, 1, rtsp ? 50 : -1);
 
     if (!tvheadend_running) { exit_flag = 1; goto done; }
-    if (rtsp && nfds == 0) {
-
-      memset(ev, 0, sizeof(ev));
-      ev[0].events             = TVHPOLL_IN;
-      ev[0].fd                 = lfe->sf_dvr_pipe.rd;
-      ev[0].data.ptr           = NULL;
-      tvhpoll_rem(efd, ev, 1);
-
-      satip_frontend_shutdown(rtsp, efd);
-
-      memset(ev, 0, sizeof(ev));
-      ev[0].events             = TVHPOLL_IN;
-      ev[0].fd                 = lfe->sf_dvr_pipe.rd;
-      ev[0].data.ptr           = NULL;
-      tvhpoll_add(efd, ev, 1);
-
-      http_client_close(rtsp);
-      rtsp = NULL;
-    }
+    if (rtsp && nfds == 0) satip_frontend_close_rtsp(lfe, efd, &rtsp);
     if (nfds <= 0) continue;
 
     if (ev[0].data.ptr == NULL) {
@@ -1280,14 +1292,17 @@ new_tune:
       lfe_master = lfe;
   }
 
-  pthread_mutex_lock(&lfe->sf_device->sd_tune_mutex);
-  u64 = lfe_master->sf_last_tune;
-  i = lfe_master->sf_tdelay;
-  pthread_mutex_unlock(&lfe->sf_device->sd_tune_mutex);
-  if (i < 0)
-    i = 0;
-  if (i > 2000)
-    i = 2000;
+  i = 0;
+  if (!rtsp) {
+    pthread_mutex_lock(&lfe->sf_device->sd_tune_mutex);
+    u64 = lfe_master->sf_last_tune;
+    i = lfe_master->sf_tdelay;
+    pthread_mutex_unlock(&lfe->sf_device->sd_tune_mutex);
+    if (i < 0)
+      i = 0;
+    if (i > 2000)
+      i = 2000;
+  }
 
   tc = 1;
   while (i) {
@@ -1329,6 +1344,15 @@ new_tune:
       goto done;
     }
 
+    if (ev[0].data.ptr == rtsp) {
+      tc = 0;
+      r = http_client_run(rtsp);
+      if (r < 0) {
+        http_client_close(rtsp);
+        rtsp = NULL;
+      }
+    }
+
   }
 
   pthread_mutex_lock(&lfe->sf_device->sd_tune_mutex);
@@ -1408,7 +1432,7 @@ new_tune:
           continue;
         } else if (b[0] == 's') {
           start = 1; running = 0;
-          goto done;
+          continue;
         }
       }
       tvhtrace("satip", "%s - input thread received mux close", buf);
@@ -1442,6 +1466,8 @@ new_tune:
         satip_frontend_tuning_error(lfe, tr);
         fatal = 1;
       } else if (r == HTTP_CON_DONE) {
+        if (start)
+          goto done;
         reply = 0;
         switch (rtsp->hc_cmd) {
         case RTSP_CMD_OPTIONS: