From patchwork Tue Mar 14 01:13:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: glenvt18 X-Patchwork-Id: 40025 Received: from localhost ([127.0.0.1] helo=www.linuxtv.org) by www.linuxtv.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cnb2Q-0006fR-Ob; Tue, 14 Mar 2017 01:14:10 +0000 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cnb2K-0006ex-Ce for vdr@linuxtv.org; Tue, 14 Mar 2017 01:14:06 +0000 X-tubIT-Incoming-IP: 209.85.215.65 Received: from mail-lf0-f65.google.com ([209.85.215.65]) by mail.tu-berlin.de (exim-4.84_2/mailfrontend-7) with esmtp for id 1cnb2I-0005BM-2z; Tue, 14 Mar 2017 02:14:04 +0100 Received: by mail-lf0-f65.google.com with SMTP id y193so13035491lfd.1 for ; Mon, 13 Mar 2017 18:14:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=YpVNmMu3lxfWO5x1JNu7ooiTMGE/YcGjIr+AZ0KaIk4=; b=ghrNWulga15sOGmuVrBYJ5KKAFBIekPpp6gVyohRusyzE03NcdxzdFcExV0f+WOKyl 6lh4/HUDG07u+IMN9ZsSzeZ1ooPU+X2bA0Z7b8gQfdEgvVEVBln9w2mY3ntJ2j6Vg2di DwcqlSF5j+g727kE2qgTNkJ9vb7NwHCRFNwO+iqhvDJ09pA4ivKIleHHHya+xXpijxMx AAXerLKL/kPQqYMYoJ0fBWO4QObgC6wZEmwFdmTiMZbttTEPdEDlRZhXJ4AIo+9eMZaP yzquSwa4XbYKqou5EGkAgwQM1HyWia5M1g/CZaAIVv9A1idDLpKiGpcUo9pPwGJ2tw5P 3DOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=YpVNmMu3lxfWO5x1JNu7ooiTMGE/YcGjIr+AZ0KaIk4=; b=fF4zp2Vy6yZ5HKbXFHnuVo6uH+ZXqDIsUCIrC56mLdgc54LV+evT4jzyukgkMCRv80 CWo6c5I057Gi89PacrYmwf/jk3xNgsxYs6P2jXsIKdZ8l39pQpspe60y94hOz10odmtg L7ixhTENm9MBEc3tZoqgmnwG+hZxliwXA2BO9t0s9G9JLpFuHw0Osmwp3bHsrDIBEWU9 y0Jl/mFdzGacZXEvmuZktoWe362kX5j4P3hKNlWqE/I4SJ8oimWmuAgeyD1WICFCLHrB Vm7N/JFBaz8PWh4NkWf5oqgIBnZRFjU8Oit6UGOW0SI14EsdCDtej6VEGtA0mcpf2xK3 sVfw== X-Gm-Message-State: AMke39nUwMb3lAPAPXA9AbFg07jS9vWmTvtWv74RoPHcxqmqA0s+JNhBIVKxCdTHzTIHQg== X-Received: by 10.25.219.18 with SMTP id s18mr8652632lfg.174.1489454041049; Mon, 13 Mar 2017 18:14:01 -0700 (PDT) Received: from localhost.localdomain ([185.135.149.183]) by smtp.gmail.com with ESMTPSA id o100sm3956361lfi.18.2017.03.13.18.14.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 13 Mar 2017 18:14:00 -0700 (PDT) From: glenvt18 To: VDR Mailing List Date: Tue, 14 Mar 2017 04:13:46 +0300 Message-Id: <1489454026-17819-1-git-send-email-glenvt18@gmail.com> X-Mailer: git-send-email 2.7.4 X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2017.3.14.10616 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' FROM_NAME_ONE_WORD 0.05, HTML_00_01 0.05, HTML_00_10 0.05, DKIM_SIGNATURE 0, NO_URI_HTTPS 0, WEBMAIL_SOURCE 0, __ANY_URI 0, __CC_NAME 0, __DATE_TZ_RU 0, __DQ_NEG_HEUR 0, __DQ_NEG_IP 0, __FRAUD_MONEY_DENOMINATION 0, __FRAUD_WEBMAIL 0, __FRAUD_WEBMAIL_FROM 0, __FROM_GMAIL 0, __HAS_CC_HDR 0, __HAS_FROM 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __MIME_TEXT_ONLY 0, __MIME_TEXT_P 0, __MIME_TEXT_P1 0, __NO_HTML_TAG_RAW 0, __PHISH_SPEAR_STRUCTURE_1 0, __RDNS_GMAIL 0, __SANE_MSGID 0, __TO_MALFORMED_2 0, __TO_NAME 0, __TO_NAME_DIFF_FROM_ACC 0, __TO_REAL_NAMES 0, __URI_NO_MAILTO 0, __URI_NO_WWW 0, __YOUTUBE_RCVD 0' X-LSpam-Score: -0.4 (/) X-LSpam-Report: No, score=-0.4 required=5.0 tests=BAYES_00=-1.9, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_SORBS_SPAM=0.5, RDNS_NONE=0.793, T_DKIM_INVALID=0.01 autolearn=no autolearn_force=no Subject: [vdr] [PATCH] Use unique recording ids for LSTR/DELR/MOVR X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: VDR Mailing List MIME-Version: 1.0 Errors-To: vdr-bounces@linuxtv.org Sender: "vdr" the way it was done with timers in 2.3.1. Using cRecordings list index as a recording id is a bad idea. If a recording is deleted between LSTR and DELR, the id passed to DELR might not be valid anymore. In VDR-2.3.2 (and, probably, in 2.3.1 too) even each subsequent DELR command in a series might invalidate the ids. For example: # echo lstr | nc 172.17.0.1 6419 220 004f7f2b0687 SVDRP VideoDiskRecorder 2.3.2; Tue Mar 7 06:25:10 2017; UTF-8 250-1 07.03.17 02:00 0:00* TEST2 250-2 07.03.17 01:00 0:00* TEST1 250-3 07.03.17 04:00 0:00* TEST4 250 4 07.03.17 03:00 0:00* TEST3 # printf "delr 2\ndelr 3\nquit\n" | nc 172.17.0.1 6419 220 004f7f2b0687 SVDRP VideoDiskRecorder 2.3.2; Tue Mar 7 06:25:51 2017; UTF-8 250 Recording "2" deleted 250 Recording "3" deleted 221 004f7f2b0687 closing connection # echo lstr | nc 172.17.0.1 6419 220 004f7f2b0687 SVDRP VideoDiskRecorder 2.3.2; Tue Mar 7 06:25:55 2017; UTF-8 250-1 07.03.17 02:00 0:00* TEST2 250 2 07.03.17 04:00 0:00* TEST4 Recording #4 (TEST3) was deleted instead of #3 (TEST4). VDR-2.2.0 handles it as expected (as 'help DELR' says): # echo lstr | nc 172.17.0.1 6419 220 004f7f2b0687 SVDRP VideoDiskRecorder 2.2.0; Tue Mar 7 06:35:13 2017; UTF-8 250-1 07.03.17 02:00 0:00* TEST2 250-2 07.03.17 01:00 0:00* TEST1 250-3 07.03.17 04:00 0:00* TEST4 250 4 07.03.17 03:00 0:00* TEST3 # printf "delr 2\ndelr 3\nquit\n" | nc 172.17.0.1 6419 220 004f7f2b0687 SVDRP VideoDiskRecorder 2.2.0; Tue Mar 7 06:35:30 2017; UTF-8 250 Recording "2" deleted 250 Recording "3" deleted 221 004f7f2b0687 closing connection # echo lstr | nc 172.17.0.1 6419 220 004f7f2b0687 SVDRP VideoDiskRecorder 2.2.0; Tue Mar 7 06:35:34 2017; UTF-8 250-1 07.03.17 02:00 0:00* TEST2 250 2 07.03.17 03:00 0:00* TEST3 Those unique ids are not persistent and don't survive VDR restarts. The same is true about timers. --- recording.c | 21 +++++++++++++++++++++ recording.h | 8 ++++++++ svdrp.c | 8 ++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/recording.c b/recording.c index 5293459..e51b82e 100644 --- a/recording.c +++ b/recording.c @@ -753,6 +753,7 @@ char *LimitNameLengths(char *s, int PathMax, int NameMax) cRecording::cRecording(cTimer *Timer, const cEvent *Event) { + id = 0; resume = RESUME_NOT_INITIALIZED; titleBuffer = NULL; sortBufferName = sortBufferTime = NULL; @@ -808,6 +809,7 @@ cRecording::cRecording(cTimer *Timer, const cEvent *Event) cRecording::cRecording(const char *FileName) { + id = 0; resume = RESUME_NOT_INITIALIZED; fileSizeMB = -1; // unknown channel = -1; @@ -1463,6 +1465,8 @@ time_t cRecordings::lastUpdate = 0; cRecordings::cRecordings(bool Deleted) :cList(Deleted ? "DelRecs" : "Recordings") { + setRecordingId = !Deleted; + lastRecordingId = 0; } cRecordings::~cRecordings() @@ -1507,6 +1511,15 @@ void cRecordings::Update(bool Wait) } } +const cRecording *cRecordings::GetById(int Id) const +{ + for (const cRecording *r = First(); r; r = Next(r)) { + if (r->Id() == Id) + return r; + } + return NULL; +} + const cRecording *cRecordings::GetByName(const char *FileName) const { if (FileName) { @@ -1518,6 +1531,14 @@ const cRecording *cRecordings::GetByName(const char *FileName) const return NULL; } +void cRecordings::Add(cRecording *Recording) +{ + if (setRecordingId) + // no need for locking, the caller must have a lock on the Recordigs list + Recording->SetId(++lastRecordingId); + cList::Add(Recording); +} + void cRecordings::AddByName(const char *FileName, bool TriggerUpdate) { if (!GetByName(FileName)) { diff --git a/recording.h b/recording.h index b649f6f..689f5de 100644 --- a/recording.h +++ b/recording.h @@ -97,6 +97,7 @@ public: class cRecording : public cListObject { friend class cRecordings; private: + int id; mutable int resume; mutable char *titleBuffer; mutable char *sortBufferName; @@ -116,6 +117,7 @@ private: static char *StripEpisodeName(char *s, bool Strip); char *SortName(void) const; void ClearSortName(void); + void SetId(int Id) { id = Id; } // should only be set by cRecordings time_t start; int priority; int lifetime; @@ -124,6 +126,7 @@ public: cRecording(cTimer *Timer, const cEvent *Event); cRecording(const char *FileName); virtual ~cRecording(); + int Id(void) const { return id; } time_t Start(void) const { return start; } int Priority(void) const { return priority; } int Lifetime(void) const { return lifetime; } @@ -220,6 +223,8 @@ class cVideoDirectoryScannerThread; class cRecordings : public cList { private: + bool setRecordingId; + int lastRecordingId; static cRecordings recordings; static cRecordings deletedRecordings; static char *updateFileName; @@ -254,8 +259,11 @@ public: static bool NeedsUpdate(void); void ResetResume(const char *ResumeFileName = NULL); void ClearSortNames(void); + const cRecording *GetById(int Id) const; + cRecording *GetById(int Id) { return const_cast(static_cast(this)->GetById(Id)); }; const cRecording *GetByName(const char *FileName) const; cRecording *GetByName(const char *FileName) { return const_cast(static_cast(this)->GetByName(FileName)); } + void Add(cRecording *Recording); void AddByName(const char *FileName, bool TriggerUpdate = true); void DelByName(const char *FileName); void UpdateByName(const char *FileName); diff --git a/svdrp.c b/svdrp.c index 1697cc6..607201c 100644 --- a/svdrp.c +++ b/svdrp.c @@ -1280,7 +1280,7 @@ void cSVDRPServer::CmdDELR(const char *Option) if (isnumber(Option)) { LOCK_RECORDINGS_WRITE; Recordings->SetExplicitModify(); - if (cRecording *Recording = Recordings->Get(strtol(Option, NULL, 10) - 1)) { + if (cRecording *Recording = Recordings->GetById(strtol(Option, NULL, 10))) { if (int RecordingInUse = Recording->IsInUse()) Reply(550, "%s", *RecordingInUseMessage(RecordingInUse, Option, Recording)); else { @@ -1707,7 +1707,7 @@ void cSVDRPServer::CmdLSTR(const char *Option) p = strtok_r(NULL, delim, &strtok_next); } if (Number) { - if (const cRecording *Recording = Recordings->Get(strtol(Option, NULL, 10) - 1)) { + if (const cRecording *Recording = Recordings->GetById(strtol(Option, NULL, 10))) { FILE *f = fdopen(file, "w"); if (f) { if (Path) @@ -1729,7 +1729,7 @@ void cSVDRPServer::CmdLSTR(const char *Option) else if (Recordings->Count()) { const cRecording *Recording = Recordings->First(); while (Recording) { - Reply(Recording == Recordings->Last() ? 250 : -250, "%d %s", Recording->Index() + 1, Recording->Title(' ', true)); + Reply(Recording == Recordings->Last() ? 250 : -250, "%d %s", Recording->Id(), Recording->Title(' ', true)); Recording = Recordings->Next(Recording); } } @@ -1940,7 +1940,7 @@ void cSVDRPServer::CmdMOVR(const char *Option) if (isnumber(num)) { LOCK_RECORDINGS_WRITE; Recordings->SetExplicitModify(); - if (cRecording *Recording = Recordings->Get(strtol(num, NULL, 10) - 1)) { + if (cRecording *Recording = Recordings->GetById(strtol(num, NULL, 10))) { if (int RecordingInUse = Recording->IsInUse()) Reply(550, "%s", *RecordingInUseMessage(RecordingInUse, Option, Recording)); else {