]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
DVR: fix the dvr_thread_epilog call (in the unlocked context)
authorJaroslav Kysela <perex@perex.cz>
Wed, 8 Feb 2017 13:14:32 +0000 (14:14 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 8 Feb 2017 13:14:35 +0000 (14:14 +0100)
- thanks are going to Glenn-1990 for the bug recognition

src/dvr/dvr_rec.c

index 5e7024628e7d81684e5fab68701def9f558224cc..5417214f1c1897fcca286197887437e4e741640b 100644 (file)
@@ -155,6 +155,7 @@ void
 dvr_rec_unsubscribe(dvr_entry_t *de)
 {
   profile_chain_t *prch = de->de_chain;
+  char *postproc = NULL;
 
   assert(de->de_s != NULL);
   assert(prch != NULL);
@@ -163,7 +164,12 @@ dvr_rec_unsubscribe(dvr_entry_t *de)
 
   atomic_add(&de->de_thread_shutdown, 1);
 
-  pthread_join(de->de_thread, NULL);
+  pthread_join(de->de_thread, (void **)&postproc);
+
+  if (prch->prch_muxer)
+    dvr_thread_epilog(de, postproc);
+
+  free(postproc);
 
   subscription_unsubscribe(de->de_s, UNSUBSCRIBE_FINAL);
   de->de_s = NULL;
@@ -1167,11 +1173,14 @@ dvr_thread_rec_start(dvr_entry_t **_de, streaming_start_t *ss,
 
     // Try to restart the recording if the muxer doesn't
     // support reconfiguration of the streams.
+    if (!dvr_thread_global_lock(de, run)) {
+      *dts_offset = PTS_UNSET;
+      *started = 0;
+      return 0;
+    }
     dvr_thread_epilog(de, postproc);
     *dts_offset = PTS_UNSET;
     *started = 0;
-    if (!dvr_thread_global_lock(de, run))
-      return 0;
     if (de->de_config->dvr_clone)
       *_de = dvr_entry_clone(de);
     dvr_thread_global_unlock(de);
@@ -1447,7 +1456,10 @@ dvr_thread(void *aux)
 
 fin:
         streaming_queue_clear(&backlog);
-       dvr_thread_epilog(de, postproc);
+        if (!dvr_thread_global_lock(de, &run))
+          break;
+        dvr_thread_epilog(de, postproc);
+        dvr_thread_global_unlock(de);
        start_time = 0;
        started = 0;
        muxing = 0;
@@ -1512,14 +1524,10 @@ fin:
 
   streaming_queue_clear(&backlog);
 
-  if (prch->prch_muxer)
-    dvr_thread_epilog(de, postproc);
-
   if (ss)
     streaming_start_unref(ss);
 
-  free(postproc);
-  return NULL;
+  return postproc;
 }
 
 /**
@@ -1577,6 +1585,8 @@ dvr_thread_epilog(dvr_entry_t *de, const char *dvr_postproc)
   htsmsg_t *e;
   htsmsg_field_t *f;
 
+  lock_assert(&global_lock);
+
   if (prch == NULL)
     return;