From: E.Smith <31170571+azlm8t@users.noreply.github.com> Date: Fri, 21 Sep 2018 10:01:09 +0000 (+0100) Subject: dvr: Mark dvr entries as duplicates early to avoid logging. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b1eb68175b29680964ebcd879e77dc0693f9586;p=thirdparty%2Ftvheadend.git dvr: Mark dvr entries as duplicates early to avoid logging. When autorecs are modified, we can do an async reschedule to ensure recordings are correctly updated in case the autorecs interact. However this can cause excessve logging in some circumstances. Effectively, if there is a recording on disk and the autorec matches the same recording in the future then the dvr_entry_create_by_autorec can exit the "bcast" loop with no match at all (since entry on disk frequently, but not always, has a null de_bcast). This then means we create the dvr_entry, and, if the programme is broadcasting now, then we immediately schedule a timer to start the recording and log an info to say scheduled. We then immediately cancel the recording, delete the dvr_entry, which then causes us do an async schedule. But this async schedule realizes the autorec matches the broadcast, so we go through the process again. So, first stage is to delete the duplicate before we do any logging. Unfortunately, due to the way dup matching works (only dvr entry vs dvr entry, not vs bcast), we have to create a dvr_entry to do the matching. We also need to check duplicate event after it is inserted in to de_global_link (to avoid assertion fault). --- diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 4c91620bc..9a1232386 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -999,6 +999,26 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone) LIST_INSERT_HEAD(&dvrentries, de, de_global_link); + /* We do early duplicate checking. Otherwise we have the scenario + * where we have a dvr entry already on disk and an autorec creates + * an entry that matches the same programme details in the future (a + * repeat), but we still create a dvr_entry for that schedule and + * then immediately cancel it when the start time arrives. So, + * instead, we cancel that duplicate here and now. + * + * Note: this check has to be done _after_ insert in to de_global_link + * otherwise the destroy will abort. + */ + if (_dvr_duplicate_event(de)) { + tvhtrace(LS_DVR, "Entry was duplicate for %s \"%s\" on \"%s\" start time %"PRId64", " + "scheduled for recording by \"%s\"", + idnode_uuid_as_str(&de->de_id, ubuf), + lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), + (int64_t)de->de_start, de->de_creator ?: ""); + dvr_entry_destroy(de, 1); + return NULL; + } + if (de->de_channel && !de->de_dont_reschedule && !clone) { LIST_FOREACH(de2, &de->de_channel->ch_dvrs, de_channel_link) if(de2 != de &&