mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
The list of recordings is now read in a separate thread
This commit is contained in:
98
recording.c
98
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;
|
||||
}
|
||||
|
||||
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 -----------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user