summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2013-12-24 14:41:09 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2013-12-24 14:41:09 +0100
commit7a2d3d993c932a12d17236f34a03f542c8943221 (patch)
treedf7233b94b8502a5fa16cd163d46c954855a6c15
parenta9acab6b7ef720a6b5f4a9059f3d7843fb83777b (diff)
downloadvdr-7a2d3d993c932a12d17236f34a03f542c8943221.tar.gz
vdr-7a2d3d993c932a12d17236f34a03f542c8943221.tar.bz2
Fixed a possible crash if the recordings list is updated externally while the Recordings menu is open
-rw-r--r--CONTRIBUTORS2
-rw-r--r--HISTORY4
-rw-r--r--recording.c69
-rw-r--r--recording.h8
-rw-r--r--vdr.c3
5 files changed, 63 insertions, 23 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 712cc136..2c37d415 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -2864,6 +2864,8 @@ Lars Hanisch <dvb@flensrocker.de>
used
for making the LIRC remote control connect to the socket even if it doesn't yet exist
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>
for adding tuning support for ATSC devices
diff --git a/HISTORY b/HISTORY
index 92fe649a..36ad3751 100644
--- a/HISTORY
+++ b/HISTORY
@@ -8032,7 +8032,7 @@ Video Disk Recorder Revision History
the last replayed recording (if any) by pressing Ok repeatedly in the Recordings
menu.
-2013-11-15: Version 2.1.3
+2013-12-24: Version 2.1.3
- Changed the return value of cPositioner::HorizonLongitude() to 0 in case the
latitude of the antenna location is beyond +/-81 degrees.
@@ -8065,3 +8065,5 @@ Video Disk Recorder Revision History
by Marko Mäkelä).
- Fixed uninitialized item area coordinates in cSkinLCARSDisplayMenu (reported by
Marko Mäkelä).
+- Fixed a possible crash if the recordings list is updated externally while the
+ Recordings menu is open (reported by Lars Hanisch).
diff --git a/recording.c b/recording.c
index d6ffb41e..f2577ab9 100644
--- a/recording.c
+++ b/recording.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.c 3.8 2013/10/20 09:51:23 kls Exp $
+ * $Id: recording.c 3.9 2013/12/24 14:32:29 kls Exp $
*/
#include "recording.h"
@@ -76,6 +76,7 @@ bool DirectoryEncoding = false;
int InstanceId = 0;
cRecordings DeletedRecordings(true);
+static cRecordings VanishedRecordings;
// --- cRemoveDeletedRecordingsThread ----------------------------------------
@@ -220,6 +221,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(const char *FileName, bool IsPesRecording)
@@ -1346,6 +1355,7 @@ cRecordings::cRecordings(bool Deleted)
:cThread("video directory scanner")
{
deleted = Deleted;
+ initial = true;
lastUpdate = 0;
state = 0;
}
@@ -1370,15 +1380,19 @@ const char *cRecordings::UpdateFileName(void)
void cRecordings::Refresh(bool Foreground)
{
lastUpdate = time(NULL); // doing this first to make sure we don't miss anything
- Lock();
- Clear();
- ChangeState();
- Unlock();
+ initial = Count() == 0; // no name checking if the list is initially empty
+ if (deleted) {
+ Lock();
+ Clear();
+ ChangeState();
+ Unlock();
+ }
ScanVideoDir(cVideoDirectory::Name(), 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);
struct dirent *e;
while ((Foreground || Running()) && (e = d.Next()) != NULL) {
@@ -1397,25 +1411,41 @@ void cRecordings::ScanVideoDir(const char *DirName, bool Foreground, int LinkLev
}
if (S_ISDIR(st.st_mode)) {
if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
- cRecording *r = new cRecording(buffer);
- if (r->Name()) {
- r->NumFrames(); // initializes the numFrames member
- r->FileSizeMB(); // initializes the fileSizeMB member
- if (deleted)
- r->deleted = time(NULL);
- Lock();
- Add(r);
- ChangeState();
- Unlock();
+ if (deleted || initial || !GetByName(buffer)) {
+ cRecording *r = new cRecording(buffer);
+ if (r->Name()) {
+ r->NumFrames(); // initializes the numFrames member
+ r->FileSizeMB(); // initializes the fileSizeMB member
+ if (deleted)
+ r->deleted = time(NULL);
+ Lock();
+ Add(r);
+ ChangeState();
+ Unlock();
+ }
+ else
+ delete r;
}
- else
- delete r;
}
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();
+ }
+ }
+ }
}
bool cRecordings::StateChanged(int &State)
@@ -1456,6 +1486,7 @@ bool cRecordings::Update(bool Wait)
cRecording *cRecordings::GetByName(const char *FileName)
{
if (FileName) {
+ LOCK_THREAD;
for (cRecording *recording = First(); recording; recording = Next(recording)) {
if (strcmp(recording->FileName(), FileName) == 0)
return recording;
diff --git a/recording.h b/recording.h
index 3b00c71b..9baed31d 100644
--- a/recording.h
+++ b/recording.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recording.h 3.1 2013/10/10 12:08:15 kls Exp $
+ * $Id: recording.h 3.2 2013/12/24 13:32:18 kls Exp $
*/
#ifndef __RECORDING_H
@@ -41,6 +41,7 @@ enum eRecordingUsage {
};
void RemoveDeletedRecordings(void);
+void ClearVanishedRecordings(void);
void AssertFreeDiskSpace(int Priority = 0, bool Force = false);
///< The special Priority value -1 means that we shall get rid of any
///< deleted recordings faster than normal (because we're cutting).
@@ -217,11 +218,12 @@ class cRecordings : public cList<cRecording>, public cThread {
private:
static char *updateFileName;
bool deleted;
+ bool initial;
time_t lastUpdate;
int state;
const char *UpdateFileName(void);
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:
void Action(void);
public:
@@ -277,6 +279,8 @@ public:
///< if all recordings have been successfully added to the RecordingsHandler.
};
+/// 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 DeletedRecordings;
diff --git a/vdr.c b/vdr.c
index 083d838c..72f3c3b9 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.tvdr.de
*
- * $Id: vdr.c 3.4 2013/10/16 09:33:58 kls Exp $
+ * $Id: vdr.c 3.5 2013/12/24 13:19:55 kls Exp $
*/
#include <getopt.h>
@@ -1369,6 +1369,7 @@ int main(int argc, char *argv[])
// Disk housekeeping:
RemoveDeletedRecordings();
+ ClearVanishedRecordings();
cSchedules::Cleanup();
// Plugins housekeeping:
PluginManager.Housekeeping();