diff options
author | Timo Eskola <timo@tolleri.net> | 2018-08-30 08:56:41 +0300 |
---|---|---|
committer | Timo Eskola <timo@tolleri.net> | 2018-08-30 08:56:41 +0300 |
commit | 1f68da4ab12ed7473208285fe7f98c8d0231a79b (patch) | |
tree | 1940b1c528ca952c282f924b8b59b96cb4775a5a | |
parent | ccf8878722725b66c78afdfdfa22d7be355f082f (diff) | |
download | vdr-plugin-duplicates-1f68da4ab12ed7473208285fe7f98c8d0231a79b.tar.gz vdr-plugin-duplicates-1f68da4ab12ed7473208285fe7f98c8d0231a79b.tar.bz2 |
Added scanner thread for duplicates.
-rw-r--r-- | HISTORY | 1 | ||||
-rw-r--r-- | duplicates.c | 4 | ||||
-rw-r--r-- | menu.c | 49 | ||||
-rw-r--r-- | menu.h | 2 | ||||
-rw-r--r-- | recording.c | 54 | ||||
-rw-r--r-- | recording.h | 22 |
6 files changed, 95 insertions, 37 deletions
@@ -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) { @@ -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(); } @@ -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 |