From: E.Smith <31170571+azlm8t@users.noreply.github.com> Date: Wed, 19 Sep 2018 13:14:37 +0000 (+0100) Subject: dvr: Async reschedule autorecs whenever a log entry is destroyed. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f01ada0dc0513ee6e628c746cd08633a5582330d;p=thirdparty%2Ftvheadend.git dvr: Async reschedule autorecs whenever a log entry is destroyed. 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. --- diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 5e0967933..9ce03d6ba 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -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) diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index c8fe54f4e..f8be3fbdb 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -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)); +} + /** * */ diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index e479fbe80..7de212fb9 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -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); }