]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
dvr: Add create time to dvr_entry and use it.
authorE.Smith <31170571+azlm8t@users.noreply.github.com>
Fri, 21 Sep 2018 17:19:28 +0000 (18:19 +0100)
committerperexg <perex@perex.cz>
Wed, 26 Sep 2018 15:30:47 +0000 (17:30 +0200)
We have to ensure we don't async reschedule if we have only just been
created then destroyed, otherwise we can enter a loop where every few
minutes the autorec is checked, realizes it can schedule against a
current broadcast, create the dvr_entry, then find it's a duplicate
of an existing recording/dvr_entry, so destroy the new entry, which
then causes the loop to start again later.

So, if a dvr_entry is created and destroy quickly then we avoid
the async reschedule. This breaks the loop since we no longer
trigger a second async reschedule.

src/dvr/dvr.h
src/dvr/dvr_db.c

index d6a57acca44e09e8634111399dded7507e0b9087..7c768e285673487024625e02ecaa1cdf69b3ea90 100644 (file)
@@ -207,7 +207,7 @@ typedef struct dvr_entry {
   LIST_ENTRY(dvr_entry) de_config_link;
 
   int de_enabled;
-
+  time_t de_create;             ///< Time entry was created
   time_t de_start;
   time_t de_stop;
 
index 597e27b4131fbc288b0847807b98f61c1eea185a..f6200629ae5b1f896277c85f47b87f1c139e5a91 100644 (file)
@@ -947,7 +947,7 @@ dvr_entry_t *
 dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone)
 {
   dvr_entry_t *de, *de2;
-  int64_t start, stop;
+  int64_t start, stop, create;
   htsmsg_t *m;
   char ubuf[UUID_HEX_SIZE], ubuf2[UUID_HEX_SIZE];
   const char *s;
@@ -979,6 +979,13 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone)
 
   idnode_load(&de->de_id, conf);
 
+  /* Time the node was created. */
+  if (!htsmsg_get_s64(conf, "create", &create)) {
+      de->de_create = create;
+  } else {
+      de->de_create = time(NULL);
+  }
+
   /* Extract episode info */
   s = htsmsg_get_str(conf, "episode");
   if (s) {
@@ -2031,8 +2038,13 @@ dvr_entry_destroy(dvr_entry_t *de, int delconf)
    * count" to be able to schedule a new recording.  We have to do
    * this even if de was not an autorec since autorecs can interact
    * with manually scheduled programmes.
+   *
+   * We avoid rescheduling for cases where the entry has only just been
+   * created and then immediately destroyed, giving a few seconds
+   * lee-way in case of slow hardware.
    */
-  dvr_autorec_async_reschedule();
+  if (!de->de_create || time(NULL) - de->de_create > 10)
+      dvr_autorec_async_reschedule();
   dvr_entry_dec_ref(de);
 }
 
@@ -2894,6 +2906,13 @@ dvr_entry_class_int_set(dvr_entry_t *de, int *v, int nv)
   return 0;
 }
 
+static int
+dvr_entry_class_create_set(void *o, const void *v)
+{
+  dvr_entry_t *de = (dvr_entry_t *)o;
+  return dvr_entry_class_time_set(de, &de->de_create, *(time_t *)v);
+}
+
 static int
 dvr_entry_class_start_set(void *o, const void *v)
 {
@@ -3794,6 +3813,15 @@ const idclass_t dvr_entry_class = {
       .desc     = N_("Enable/disable the entry."),
       .off      = offsetof(dvr_entry_t, de_enabled),
     },
+    {
+      .type     = PT_TIME,
+      .id       = "create",
+      .name     = N_("Time the entry was created"),
+      .desc     = N_("The create time of the entry describing the recording."),
+      .set      = dvr_entry_class_create_set,
+      .off      = offsetof(dvr_entry_t, de_create),
+      .opts     = PO_HIDDEN | PO_RDONLY | PO_NOUI,
+    },
     {
       .type     = PT_TIME,
       .id       = "start",