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<cRecording>(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<cRecording>::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<cRecording> { 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<cRecording *>(static_cast<const cRecordings *>(this)->GetById(Id)); }; const cRecording *GetByName(const char *FileName) const; cRecording *GetByName(const char *FileName) { return const_cast<cRecording *>(static_cast<const cRecordings *>(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 { -- Sergey Chernyavskiy _______________________________________________ vdr mailing list vdr@xxxxxxxxxxx https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr