summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Eskola <timo@tolleri.net>2018-08-30 08:56:41 +0300
committerTimo Eskola <timo@tolleri.net>2018-08-30 08:56:41 +0300
commit1f68da4ab12ed7473208285fe7f98c8d0231a79b (patch)
tree1940b1c528ca952c282f924b8b59b96cb4775a5a
parentccf8878722725b66c78afdfdfa22d7be355f082f (diff)
downloadvdr-plugin-duplicates-1f68da4ab12ed7473208285fe7f98c8d0231a79b.tar.gz
vdr-plugin-duplicates-1f68da4ab12ed7473208285fe7f98c8d0231a79b.tar.bz2
Added scanner thread for duplicates.
-rw-r--r--HISTORY1
-rw-r--r--duplicates.c4
-rw-r--r--menu.c49
-rw-r--r--menu.h2
-rw-r--r--recording.c54
-rw-r--r--recording.h22
6 files changed, 95 insertions, 37 deletions
diff --git a/HISTORY b/HISTORY
index bd393cf..3e154dd 100644
--- a/HISTORY
+++ b/HISTORY
@@ -3,6 +3,7 @@ VDR Plugin 'duplicates' Revision History
20??-??-??: Version 1.0.0
- Dropped support for VDR 2.2.0.
+- Added scanner thread for duplicates.
2018-08-29: Version 0.2.0
diff --git a/duplicates.c b/duplicates.c
index f22de62..c1c5f12 100644
--- a/duplicates.c
+++ b/duplicates.c
@@ -10,7 +10,7 @@
#include <vdr/plugin.h>
#include "config.h"
#include "menu.h"
-#include "visibility.h"
+#include "recording.h"
static const char *VERSION = "1.0.0-SNAPSHOT";
static const char *DESCRIPTION = trNOOP("Shows duplicate recordings");
@@ -69,11 +69,13 @@ bool cPluginDuplicates::Initialize(void) {
bool cPluginDuplicates::Start(void) {
// Start any background activities the plugin shall perform.
+ DuplicateRecordingScanner.Start();
return true;
}
void cPluginDuplicates::Stop(void) {
// Stop any background activities the plugin is performing.
+ DuplicateRecordingScanner.Stop();
}
void cPluginDuplicates::Housekeeping(void) {
diff --git a/menu.c b/menu.c
index 88f180c..d2c8562 100644
--- a/menu.c
+++ b/menu.c
@@ -147,28 +147,29 @@ void cMenuDuplicates::SetHelpKeys(void) {
}
void cMenuDuplicates::Set(bool Refresh) {
- DuplicateRecordings.Update();
- const char *CurrentRecording = NULL;
- int currentIndex = -1;
- if (Refresh)
- currentIndex = Current();
- else
- CurrentRecording = cReplayControl::LastReplayed();
- cMutexLock MutexLock(&DuplicateRecordings.mutex);
- for (cDuplicateRecording *Duplicates = DuplicateRecordings.First(); Duplicates; Duplicates = DuplicateRecordings.Next(Duplicates)) {
- Add(SeparatorItem(Duplicates->Text()));
- for (cDuplicateRecording *Duplicate = Duplicates->Duplicates()->First(); Duplicate; Duplicate = Duplicates->Duplicates()->Next(Duplicate)) {
- cMenuDuplicateItem *Item = new cMenuDuplicateItem(Duplicate);
- Add(Item);
- if (CurrentRecording && strcmp(CurrentRecording, Item->FileName()) == 0)
- SetCurrent(Item);
+ if (DuplicateRecordings.Lock(duplicateRecordingsStateKey)) {
+ const char *CurrentRecording = NULL;
+ int currentIndex = -1;
+ if (Refresh)
+ currentIndex = Current();
+ else
+ CurrentRecording = cReplayControl::LastReplayed();
+ for (cDuplicateRecording *Duplicates = DuplicateRecordings.First(); Duplicates; Duplicates = DuplicateRecordings.Next(Duplicates)) {
+ Add(SeparatorItem(Duplicates->Text()));
+ for (cDuplicateRecording *Duplicate = Duplicates->Duplicates()->First(); Duplicate; Duplicate = Duplicates->Duplicates()->Next(Duplicate)) {
+ cMenuDuplicateItem *Item = new cMenuDuplicateItem(Duplicate);
+ Add(Item);
+ if (CurrentRecording && strcmp(CurrentRecording, Item->FileName()) == 0)
+ SetCurrent(Item);
+ }
+ }
+ duplicateRecordingsStateKey.Remove();
+ if (Count() == 0)
+ Add(SeparatorItem(cString::sprintf(tr("%d duplicate recordings"), 0)));
+ if (Refresh) {
+ SetCurrentIndex(currentIndex);
+ Display();
}
- }
- if (Count() == 0)
- Add(SeparatorItem(cString::sprintf(tr("%d duplicate recordings"), 0)));
- if (Refresh) {
- SetCurrentIndex(currentIndex);
- Display();
}
}
@@ -284,6 +285,7 @@ eOSState cMenuDuplicates::Delete(void) {
RecordingsHandler.Del(FileName); // must do this w/o holding a lock, because the cleanup section in cDirCopier::Action() might request one!
if (cReplayControl::NowReplaying() && strcmp(cReplayControl::NowReplaying(), FileName) == 0)
cControl::Shutdown();
+ cStateKey recordingsStateKey;
cRecordings *Recordings = cRecordings::GetRecordingsWrite(recordingsStateKey);
Recordings->SetExplicitModify();
cRecording *recording = Recordings->GetByName(FileName);
@@ -380,10 +382,7 @@ eOSState cMenuDuplicates::ProcessKey(eKeys Key) {
}
}
if (!HasSubMenu()) {
- if (cRecordings::GetRecordingsRead(recordingsStateKey)) {
- recordingsStateKey.Remove();
- Set(true);
- }
+ Set(true);
if (Key != kNone)
SetHelpKeys();
}
diff --git a/menu.h b/menu.h
index 2cb5f41..ac43d9b 100644
--- a/menu.h
+++ b/menu.h
@@ -25,7 +25,7 @@ class cMenuSetupDuplicates;
class cMenuDuplicates : public cOsdMenu {
friend class cMenuSetupDuplicates;
private:
- cStateKey recordingsStateKey;
+ cStateKey duplicateRecordingsStateKey;
int helpKeys;
void SetHelpKeys(void);
void Set(bool Refresh = false);
diff --git a/recording.c b/recording.c
index 96db78a..4cb5f7d 100644
--- a/recording.c
+++ b/recording.c
@@ -81,21 +81,54 @@ bool cDuplicateRecording::IsDuplicate(cDuplicateRecording *DuplicateRecording) {
// --- cDuplicateRecordings ------------------------------------------------------
-cDuplicateRecordings::cDuplicateRecordings(void) {}
+cDuplicateRecordings::cDuplicateRecordings(void) : cList("duplicates") {}
-void cDuplicateRecordings::Update(void) {
+cDuplicateRecordings DuplicateRecordings;
+
+// --- cDuplicateRecordingScannerThread ------------------------------------------
+
+cDuplicateRecordingScannerThread::cDuplicateRecordingScannerThread() : cThread("duplicate recording scanner", true) {
+ title = dc.title;
+ hidden = dc.hidden;
+}
+
+cDuplicateRecordingScannerThread::~cDuplicateRecordingScannerThread(){
+ Stop();
+}
+
+void cDuplicateRecordingScannerThread::Stop() {
+ Cancel(3);
+}
+
+void cDuplicateRecordingScannerThread::Action(void) {
+ while (Running()) {
+ if (title != dc.title || hidden != dc.hidden) {
+ recordingsStateKey.Reset();
+ title = dc.title;
+ hidden = dc.hidden;
+ }
+ if (cRecordings::GetRecordingsRead(recordingsStateKey)) {
+ recordingsStateKey.Remove();
+ Scan();
+ }
+ if (Running())
+ cCondWait::SleepMs(250);
+ }
+}
+
+void cDuplicateRecordingScannerThread::Scan(void) {
struct timeval startTime, stopTime;
gettimeofday(&startTime, NULL);
- cMutexLock MutexLock(&mutex);
+ cStateKey duplicateRecordingsStateKey;
+ DuplicateRecordings.Lock(duplicateRecordingsStateKey, true);
#ifdef DEBUG_VISIBILITY
cVisibility::ClearCounters();
int isDuplicateCount = 0;
#endif
cDuplicateRecording *descriptionless = new cDuplicateRecording();
cList<cDuplicateRecording> recordings;
- Clear();
+ DuplicateRecordings.Clear();
{
- cStateKey recordingsStateKey;
cRecordings *Recordings = cRecordings::GetRecordingsWrite(recordingsStateKey); // write access is necessary for sorting!
Recordings->Sort();
for (const cRecording *recording = Recordings->First(); recording; recording = Recordings->Next(recording)) {
@@ -108,6 +141,10 @@ void cDuplicateRecordings::Update(void) {
recordingsStateKey.Remove(false); // sorting doesn't count as a real modification
}
for (cDuplicateRecording *recording = recordings.First(); recording; recording = recordings.Next(recording)) {
+ if (!Running())
+ return;
+ if (cIoThrottle::Engaged())
+ cCondWait::SleepMs(100);
if (!recording->Checked()) {
recording->SetChecked();
cDuplicateRecording *duplicates = new cDuplicateRecording();
@@ -125,16 +162,17 @@ void cDuplicateRecordings::Update(void) {
}
if (duplicates->Duplicates()->Count() > 1) {
duplicates->SetText(cString::sprintf(tr("%d duplicate recordings"), duplicates->Duplicates()->Count()));
- Add(duplicates);
+ DuplicateRecordings.Add(duplicates);
} else
delete duplicates;
}
}
if (descriptionless->Duplicates()->Count() > 0) {
descriptionless->SetText(cString::sprintf(tr("%d recordings without description"), descriptionless->Duplicates()->Count()));
- Add(descriptionless);
+ DuplicateRecordings.Add(descriptionless);
} else
delete descriptionless;
+ duplicateRecordingsStateKey.Remove();
gettimeofday(&stopTime, NULL);
double seconds = (((long long)stopTime.tv_sec * 1000000 + stopTime.tv_usec) - ((long long)startTime.tv_sec * 1000000 + startTime.tv_usec)) / 1000000.0;
#ifdef DEBUG_VISIBILITY
@@ -145,5 +183,5 @@ void cDuplicateRecordings::Update(void) {
#endif
}
-cDuplicateRecordings DuplicateRecordings;
+cDuplicateRecordingScannerThread DuplicateRecordingScanner;
diff --git a/recording.h b/recording.h
index 0987af4..ce766cc 100644
--- a/recording.h
+++ b/recording.h
@@ -40,13 +40,31 @@ public:
cList<cDuplicateRecording> *Duplicates(void) { return duplicates; }
};
+// --- cDuplicateRecordings ------------------------------------------------------
+
class cDuplicateRecordings : public cList<cDuplicateRecording> {
public:
cDuplicateRecordings(void);
- cMutex mutex;
- void Update(void);
};
extern cDuplicateRecordings DuplicateRecordings;
+// --- cDuplicateRecordingScannerThread ------------------------------------------
+
+class cDuplicateRecordingScannerThread : public cThread {
+private:
+ cStateKey recordingsStateKey;
+ int title;
+ int hidden;
+ void Scan(void);
+protected:
+ virtual void Action(void);
+public:
+ cDuplicateRecordingScannerThread();
+ ~cDuplicateRecordingScannerThread();
+ void Stop(void);
+};
+
+extern cDuplicateRecordingScannerThread DuplicateRecordingScanner;
+
#endif