From: E.Smith <31170571+azlm8t@users.noreply.github.com> Date: Fri, 21 Sep 2018 17:19:28 +0000 (+0100) Subject: dvr: Add create time to dvr_entry and use it. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4eed46988fb398995543f80efbc9dce9d392329;p=thirdparty%2Ftvheadend.git dvr: Add create time to dvr_entry and use it. 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. --- diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index d6a57acca..7c768e285 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -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; diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 597e27b41..f6200629a 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -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",