From 9e8aac388237e7afff6cae5bbf5ee08756633f53 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 25 Sep 2005 11:00:57 +0200 Subject: The list of recordings is now read in a separate thread --- recording.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 19 deletions(-) (limited to 'recording.c') diff --git a/recording.c b/recording.c index 4a12b71e..ccdb71c4 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 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; +} + +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) +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::StateChanged(int &State) +{ + int NewState = state; + bool Result = State != NewState; + State = state; + return Result; +} + bool cRecordings::NeedsUpdate(void) { - return lastUpdate <= LastModifiedTime(AddDirectory(VideoDirectory, ".update")); + return lastUpdate < LastModifiedTime(AddDirectory(VideoDirectory, ".update")); } -bool cRecordings::Load(void) +bool cRecordings::Update(bool Wait) { - lastUpdate = time(NULL); // doing this first to make sure we don't miss anything - Clear(); - ScanVideoDir(VideoDirectory); - Sort(); - return Count() > 0; + 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 ----------------------------------------------------------------- -- cgit v1.2.3