1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed a possible crash if the recordings list is updated externally while the Recordings menu is open

This commit is contained in:
Klaus Schmidinger 2013-12-25 10:57:36 +01:00
parent cca9d858a7
commit 1045069fee
5 changed files with 56 additions and 19 deletions

View File

@ -2851,6 +2851,8 @@ Lars Hanisch <dvb@flensrocker.de>
used used
for making the LIRC remote control connect to the socket even if it doesn't yet exist for making the LIRC remote control connect to the socket even if it doesn't yet exist
when VDR is started when VDR is started
for reporting a possible crash if the recordings list is updated externally while the
Recordings menu is open
Alex Lasnier <alex@fepg.org> Alex Lasnier <alex@fepg.org>
for adding tuning support for ATSC devices for adding tuning support for ATSC devices

View File

@ -7854,7 +7854,7 @@ Video Disk Recorder Revision History
the last replayed recording (if any) by pressing Ok repeatedly in the Recordings the last replayed recording (if any) by pressing Ok repeatedly in the Recordings
menu. menu.
2013-11-16: Version 2.0.5 2013-12-25: Version 2.0.5
- The LIRC remote control now connects to the socket even if it doesn't yet exist when - The LIRC remote control now connects to the socket even if it doesn't yet exist when
VDR is started (thanks to Lars Hanisch). VDR is started (thanks to Lars Hanisch).
@ -7862,3 +7862,5 @@ Video Disk Recorder Revision History
Marko Mäkelä). Marko Mäkelä).
- Fixed uninitialized item area coordinates in cSkinLCARSDisplayMenu (reported by - Fixed uninitialized item area coordinates in cSkinLCARSDisplayMenu (reported by
Marko Mäkelä). Marko Mäkelä).
- Fixed a possible crash if the recordings list is updated externally while the
Recordings menu is open (reported by Lars Hanisch).

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recording.c 2.91.1.2 2013/08/21 13:58:35 kls Exp $ * $Id: recording.c 2.91.1.3 2013/12/25 10:55:32 kls Exp $
*/ */
#include "recording.h" #include "recording.h"
@ -72,6 +72,7 @@ bool DirectoryEncoding = false;
int InstanceId = 0; int InstanceId = 0;
cRecordings DeletedRecordings(true); cRecordings DeletedRecordings(true);
static cRecordings VanishedRecordings;
// --- cRemoveDeletedRecordingsThread ---------------------------------------- // --- cRemoveDeletedRecordingsThread ----------------------------------------
@ -216,6 +217,14 @@ void AssertFreeDiskSpace(int Priority, bool Force)
} }
} }
// --- Clear vanished recordings ---------------------------------------------
void ClearVanishedRecordings(void)
{
cThreadLock RecordingsLock(&Recordings); // yes, it *is* Recordings!
VanishedRecordings.Clear();
}
// --- cResumeFile ----------------------------------------------------------- // --- cResumeFile -----------------------------------------------------------
cResumeFile::cResumeFile(const char *FileName, bool IsPesRecording) cResumeFile::cResumeFile(const char *FileName, bool IsPesRecording)
@ -1233,6 +1242,7 @@ cRecordings::cRecordings(bool Deleted)
:cThread("video directory scanner") :cThread("video directory scanner")
{ {
deleted = Deleted; deleted = Deleted;
initial = true;
lastUpdate = 0; lastUpdate = 0;
state = 0; state = 0;
} }
@ -1264,8 +1274,9 @@ void cRecordings::Refresh(bool Foreground)
ScanVideoDir(VideoDirectory, Foreground); ScanVideoDir(VideoDirectory, Foreground);
} }
void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLevel) void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLevel, int DirLevel)
{ {
// Find any new recordings:
cReadDir d(DirName); cReadDir d(DirName);
struct dirent *e; struct dirent *e;
while ((Foreground || Running()) && (e = d.Next()) != NULL) { while ((Foreground || Running()) && (e = d.Next()) != NULL) {
@ -1284,6 +1295,7 @@ void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLev
} }
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode)) {
if (endswith(buffer, deleted ? DELEXT : RECEXT)) { if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
if (deleted || initial || !GetByName(buffer)) {
cRecording *r = new cRecording(buffer); cRecording *r = new cRecording(buffer);
if (r->Name()) { if (r->Name()) {
r->NumFrames(); // initializes the numFrames member r->NumFrames(); // initializes the numFrames member
@ -1298,8 +1310,23 @@ void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLev
else else
delete r; delete r;
} }
}
else else
ScanVideoDir(buffer, Foreground, LinkLevel + Link); ScanVideoDir(buffer, Foreground, LinkLevel + Link, DirLevel + 1);
}
}
}
// Handle any vanished recordings:
if (!deleted && !initial && DirLevel == 0) {
for (cRecording *recording = First(); recording; ) {
cRecording *r = recording;
recording = Next(recording);
if (access(r->FileName(), F_OK) != 0) {
Lock();
Del(r, false);
VanishedRecordings.Add(r);
ChangeState();
Unlock();
} }
} }
} }
@ -1343,6 +1370,7 @@ bool cRecordings::Update(bool Wait)
cRecording *cRecordings::GetByName(const char *FileName) cRecording *cRecordings::GetByName(const char *FileName)
{ {
if (FileName) { if (FileName) {
LOCK_THREAD;
for (cRecording *recording = First(); recording; recording = Next(recording)) { for (cRecording *recording = First(); recording; recording = Next(recording)) {
if (strcmp(recording->FileName(), FileName) == 0) if (strcmp(recording->FileName(), FileName) == 0)
return recording; return recording;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recording.h 2.46 2013/03/04 14:01:23 kls Exp $ * $Id: recording.h 2.46.1.1 2013/12/25 10:54:05 kls Exp $
*/ */
#ifndef __RECORDING_H #ifndef __RECORDING_H
@ -26,6 +26,7 @@ extern bool DirectoryEncoding;
extern int InstanceId; extern int InstanceId;
void RemoveDeletedRecordings(void); void RemoveDeletedRecordings(void);
void ClearVanishedRecordings(void);
void AssertFreeDiskSpace(int Priority = 0, bool Force = false); void AssertFreeDiskSpace(int Priority = 0, bool Force = false);
///< The special Priority value -1 means that we shall get rid of any ///< The special Priority value -1 means that we shall get rid of any
///< deleted recordings faster than normal (because we're cutting). ///< deleted recordings faster than normal (because we're cutting).
@ -160,11 +161,12 @@ class cRecordings : public cList<cRecording>, public cThread {
private: private:
static char *updateFileName; static char *updateFileName;
bool deleted; bool deleted;
bool initial;
time_t lastUpdate; time_t lastUpdate;
int state; int state;
const char *UpdateFileName(void); const char *UpdateFileName(void);
void Refresh(bool Foreground = false); void Refresh(bool Foreground = false);
void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0); void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0, int DirLevel = 0);
protected: protected:
void Action(void); void Action(void);
public: public:
@ -199,6 +201,8 @@ public:
///< this value is unknown. ///< this value is unknown.
}; };
/// Any access to Recordings that loops through the list of recordings
/// needs to hold a thread lock on this object!
extern cRecordings Recordings; extern cRecordings Recordings;
extern cRecordings DeletedRecordings; extern cRecordings DeletedRecordings;

3
vdr.c
View File

@ -22,7 +22,7 @@
* *
* The project's page is at http://www.tvdr.de * The project's page is at http://www.tvdr.de
* *
* $Id: vdr.c 2.57.1.1 2013/10/16 09:46:36 kls Exp $ * $Id: vdr.c 2.57.1.2 2013/12/25 10:54:36 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
@ -1360,6 +1360,7 @@ int main(int argc, char *argv[])
// Disk housekeeping: // Disk housekeeping:
RemoveDeletedRecordings(); RemoveDeletedRecordings();
ClearVanishedRecordings();
cSchedules::Cleanup(); cSchedules::Cleanup();
// Plugins housekeeping: // Plugins housekeeping:
PluginManager.Housekeeping(); PluginManager.Housekeeping();