]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
dvr: Async reschedule autorecs whenever a log entry is destroyed.
authorE.Smith <31170571+azlm8t@users.noreply.github.com>
Wed, 19 Sep 2018 13:14:37 +0000 (14:14 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 20 Sep 2018 12:34:19 +0000 (14:34 +0200)
Destroying a log entry can cause another autorec rule to be valid and
need scheduling.

For example, if you have two autorec rules that match the same
programme then only one autorec rule will schedule the programme
and the other autorec will see the programme is scheduled and do
nothing.

However, if you then disable the first autorec rule, then we need the
second autorec rule to re-arm the timer for that programme since it
still matches it.

This resheduling is done async after a delay. This avoids large
changes causing constant rescheduling. So, if user deletes a thousand
log files, we do not want a thousand reschedules to occur. Instead,
we dispatch a single timer after the last update has occurred.

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

index 5e0967933c15aa482deaa622e243ecb8c9b865ca..9ce03d6ba9f220b9a2133df2e63b8557361963af 100644 (file)
@@ -701,6 +701,8 @@ void dvr_autorec_init(void);
 void dvr_autorec_done(void);
 
 void dvr_autorec_update(void);
+/// Check autorec timers after a short delay.
+void dvr_autorec_async_reschedule(void);
 
 static inline int
   dvr_autorec_entry_verify(dvr_autorec_entry_t *dae, access_t *a, int readonly)
index c8fe54f4e3824466830118dc0852a888f1d880ce..f8be3fbdb263d3a1ca99e5269c24833b44c00d3f 100644 (file)
@@ -1411,6 +1411,29 @@ dvr_autorec_update(void)
   }
 }
 
+static void
+dvr_autorec_async_reschedule_cb(void *ignored)
+{
+  tvhdebug(LS_DVR, "dvr_autorec_async_reschedule_cb - begin");
+  dvr_autorec_update();
+  tvhdebug(LS_DVR, "dvr_autorec_async_reschedule_cb - end");
+}
+
+void
+dvr_autorec_async_reschedule(void)
+{
+  tvhtrace(LS_DVR, "dvr_autorec_async_reschedule");
+  static mtimer_t reschedule_timer;
+  mtimer_disarm(&reschedule_timer);
+  /* We schedule the update after a brief period. This allows the
+   * system to quiesce in case the user is doing a large operation
+   * such as deleting numerous records due to disabling an autorec
+   * rule.
+   */
+  mtimer_arm_rel(&reschedule_timer, dvr_autorec_async_reschedule_cb, NULL,
+                 sec2mono(60));
+}
+
 /**
  *
  */
index e479fbe80859d3c878803e2189d29a25182d7725..7de212fb9af3d51e5f00329d7ec90b378c664540 100644 (file)
@@ -1894,9 +1894,10 @@ dvr_entry_create_by_autorec(int enabled, epg_broadcast_t *e, dvr_autorec_entry_t
       if ((de->de_sched_state == DVR_SCHEDULED) ||
           (de->de_sched_state == DVR_RECORDING)) count++;
 
+    /* We drop this to a debug since on a reschedule numerous emitted */
     if (count >= max_count) {
-      tvhinfo(LS_DVR, "Autorecord \"%s\": Not scheduling \"%s\" because of autorecord max schedules limit reached",
-              dae->dae_name, lang_str_get(e->title, NULL));
+      tvhdebug(LS_DVR, "Autorecord \"%s\": Not scheduling \"%s\" because of autorecord max schedules limit reached",
+               dae->dae_name, lang_str_get(e->title, NULL));
       return;
     }
   }
@@ -2005,6 +2006,13 @@ dvr_entry_destroy(dvr_entry_t *de, int delconf)
   if (de->de_child)
     dvr_entry_change_parent_child(de, NULL, de, delconf);
 
+  /* Trigger a reschedule in case this entry affects an autorec.  For
+   * example, deleting a recording could cause an autorec with a "max
+   * 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.
+   */
+  dvr_autorec_async_reschedule();
   dvr_entry_dec_ref(de);
 }