The list of recordings is now read in a separate thread

This commit is contained in:
Klaus Schmidinger
2005-09-25 11:00:57 +02:00
parent 83985eff47
commit 9e8aac3882
8 changed files with 178 additions and 63 deletions

View File

@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: recording.c 1.114 2005/09/17 09:14:36 kls Exp $
* $Id: recording.c 1.115 2005/09/25 10:40:31 kls Exp $
*/
#include "recording.h"
@@ -60,17 +60,23 @@
bool VfatFileSystem = false;
static cRecordings DeletedRecordings(true);
void RemoveDeletedRecordings(void)
{
static time_t LastRemoveCheck = 0;
if (time(NULL) - LastRemoveCheck > REMOVECHECKDELTA) {
if (LastRemoveCheck == 0) {
DeletedRecordings.Update();
LastRemoveCheck = time(NULL) - REMOVECHECKDELTA * 9 / 10;
}
else if (time(NULL) - LastRemoveCheck > REMOVECHECKDELTA) {
// Make sure only one instance of VDR does this:
cLockFile LockFile(VideoDirectory);
if (!LockFile.Lock())
return;
// Remove the oldest file that has been "deleted":
cRecordings DeletedRecordings(true);
if (DeletedRecordings.Load()) {
cThreadLock DeletedRecordingsLock(&DeletedRecordings);
if (DeletedRecordings.Count()) {
cRecording *r = DeletedRecordings.First();
cRecording *r0 = r;
while (r) {
@@ -80,11 +86,14 @@ void RemoveDeletedRecordings(void)
}
if (r0 && time(NULL) - r0->start > DELETEDLIFETIME * 3600) {
r0->Remove();
DeletedRecordings.Del(r0);
RemoveEmptyVideoDirectories();
LastRemoveCheck += REMOVELATENCY;
return;
}
}
else
DeletedRecordings.Update();
LastRemoveCheck = time(NULL);
}
}
@@ -104,8 +113,8 @@ void AssertFreeDiskSpace(int Priority)
return;
// Remove the oldest file that has been "deleted":
isyslog("low disk space while recording, trying to remove a deleted recording...");
cRecordings DeletedRecordings(true);
if (DeletedRecordings.Load()) {
cThreadLock DeletedRecordingsLock(&DeletedRecordings);
if (DeletedRecordings.Count()) {
cRecording *r = DeletedRecordings.First();
cRecording *r0 = r;
while (r) {
@@ -114,13 +123,20 @@ void AssertFreeDiskSpace(int Priority)
r = DeletedRecordings.Next(r);
}
if (r0 && r0->Remove()) {
DeletedRecordings.Del(r0);
LastFreeDiskCheck += REMOVELATENCY / Factor;
return;
}
}
// DeletedRecordings was empty, so to be absolutely sure there are no
// deleted recordings we need to double check:
DeletedRecordings.Update(true);
if (DeletedRecordings.Count())
return; // the next call will actually remove it
// No "deleted" files to remove, so let's see if we can delete a recording:
isyslog("...no deleted recording found, trying to delete an old recording...");
if (Recordings.Load()) {
cThreadLock RecordingsLock(&Recordings);
if (Recordings.Count()) {
cRecording *r = Recordings.First();
cRecording *r0 = NULL;
while (r) {
@@ -454,6 +470,7 @@ cRecording::cRecording(const char *FileName)
name[p - FileName] = 0;
name = ExchangeChars(name, false);
}
GetResume();
// read an optional info file:
char *InfoFileName = NULL;
asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX);
@@ -720,16 +737,38 @@ bool cRecording::Remove(void)
cRecordings Recordings;
cRecordings::cRecordings(bool Deleted)
:cThread("video directory scanner")
{
deleted = Deleted;
lastUpdate = 0;
state = 0;
}
void cRecordings::ScanVideoDir(const char *DirName)
cRecordings::~cRecordings()
{
Cancel(3);
}
void cRecordings::Action(void)
{
Refresh();
}
void cRecordings::Refresh(bool Foreground)
{
lastUpdate = time(NULL); // doing this first to make sure we don't miss anything
Lock();
Clear();
ChangeState();
Unlock();
ScanVideoDir(VideoDirectory, Foreground);
}
void cRecordings::ScanVideoDir(const char *DirName, bool Foreground)
{
cReadDir d(DirName);
struct dirent *e;
while ((e = d.Next()) != NULL) {
while ((Foreground || Running()) && (e = d.Next()) != NULL) {
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
char *buffer;
asprintf(&buffer, "%s/%s", DirName, e->d_name);
@@ -749,13 +788,17 @@ void cRecordings::ScanVideoDir(const char *DirName)
if (S_ISDIR(st.st_mode)) {
if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
cRecording *r = new cRecording(buffer);
if (r->Name())
if (r->Name()) {
Lock();
Add(r);
ChangeState();
Unlock();
}
else
delete r;
}
else
ScanVideoDir(buffer);
ScanVideoDir(buffer, Foreground);
}
}
free(buffer);
@@ -763,18 +806,28 @@ void cRecordings::ScanVideoDir(const char *DirName)
}
}
bool cRecordings::NeedsUpdate(void)
bool cRecordings::StateChanged(int &State)
{
return lastUpdate <= LastModifiedTime(AddDirectory(VideoDirectory, ".update"));
int NewState = state;
bool Result = State != NewState;
State = state;
return Result;
}
bool cRecordings::Load(void)
bool cRecordings::NeedsUpdate(void)
{
lastUpdate = time(NULL); // doing this first to make sure we don't miss anything
Clear();
ScanVideoDir(VideoDirectory);
Sort();
return Count() > 0;
return lastUpdate < LastModifiedTime(AddDirectory(VideoDirectory, ".update"));
}
bool cRecordings::Update(bool Wait)
{
if (Wait) {
Refresh(true);
return Count() > 0;
}
else
Start();
return false;
}
cRecording *cRecordings::GetByName(const char *FileName)
@@ -788,18 +841,23 @@ cRecording *cRecordings::GetByName(const char *FileName)
void cRecordings::AddByName(const char *FileName)
{
LOCK_THREAD;
cRecording *recording = GetByName(FileName);
if (!recording) {
recording = new cRecording(FileName);
Add(recording);
ChangeState();
}
}
void cRecordings::DelByName(const char *FileName)
{
LOCK_THREAD;
cRecording *recording = GetByName(FileName);
if (recording)
if (recording) {
Del(recording);
ChangeState();
}
}
// --- cMark -----------------------------------------------------------------