1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Moved cleaning up the EPG data and writing the epg.data file into a separate thread to avoid sluggish response to user input on slow systems

This commit is contained in:
Klaus Schmidinger 2012-09-24 13:41:54 +02:00
parent 7cdfca45f4
commit 6f1577a659
5 changed files with 89 additions and 33 deletions

View File

@ -2955,3 +2955,7 @@ Jens Vogel <jens.vogel@akjv.de>
for suggesting to make cPatPmtParser::ParsePmt() also recognize stream type 0x81 for suggesting to make cPatPmtParser::ParsePmt() also recognize stream type 0x81
as "AC3", so that recordings that have been converted from the old PES format to as "AC3", so that recordings that have been converted from the old PES format to
TS can be played TS can be played
Sören Moch <smoch@web.de>
for a patch that was used to move cleaning up the EPG data and writing the epg.data
file into a separate thread to avoid sluggish response to user input on slow systems

View File

@ -7235,7 +7235,7 @@ Video Disk Recorder Revision History
function in order to make use of this new feature. See, for instance, the function function in order to make use of this new feature. See, for instance, the function
cSkinClassicDisplayMenu::SetButtons() in skinclassic.c for details. cSkinClassicDisplayMenu::SetButtons() in skinclassic.c for details.
2012-09-22: Version 1.7.31 2012-09-24: Version 1.7.31
- If regenerating an index file fails and no data is written to the file, VDR now - If regenerating an index file fails and no data is written to the file, VDR now
reports this error and removes the empty index file. reports this error and removes the empty index file.
@ -7258,3 +7258,6 @@ Video Disk Recorder Revision History
mechanism if they use intense background I/O. mechanism if they use intense background I/O.
- Increased the size of the TS buffer to 5MB and that of the Recorder buffer to - Increased the size of the TS buffer to 5MB and that of the Recorder buffer to
20MB to better handle HD recordings (suggested by Torsten Lang). 20MB to better handle HD recordings (suggested by Torsten Lang).
- Moved cleaning up the EPG data and writing the epg.data file into a separate
thread to avoid sluggish response to user input on slow systems (based on a patch from
Sören Moch).

100
epg.c
View File

@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by * Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* *
* $Id: epg.c 2.18 2012/08/25 11:10:29 kls Exp $ * $Id: epg.c 2.19 2012/09/24 13:24:02 kls Exp $
*/ */
#include "epg.h" #include "epg.h"
@ -18,6 +18,7 @@
#include "timers.h" #include "timers.h"
#define RUNNINGSTATUSTIMEOUT 30 // seconds before the running status is considered unknown #define RUNNINGSTATUSTIMEOUT 30 // seconds before the running status is considered unknown
#define EPGDATAWRITEDELTA 600 // seconds between writing the epg.data file
// --- tComponent ------------------------------------------------------------ // --- tComponent ------------------------------------------------------------
@ -581,9 +582,20 @@ static void EpgBugFixStat(int Number, tChannelID ChannelID)
} }
} }
void ReportEpgBugFixStats(bool Reset) void ReportEpgBugFixStats(bool Force)
{ {
if (Setup.EPGBugfixLevel > 0) { if (Setup.EPGBugfixLevel > 0) {
static time_t LastReport = 0;
time_t now = time(NULL);
if (now - LastReport > 3600 || Force) {
LastReport = now;
struct tm tm_r;
struct tm *ptm = localtime_r(&now, &tm_r);
if (ptm->tm_hour != 5)
return;
}
else
return;
bool GotHits = false; bool GotHits = false;
char buffer[1024]; char buffer[1024];
for (int i = 0; i < MAXEPGBUGFIXSTATS; i++) { for (int i = 0; i < MAXEPGBUGFIXSTATS; i++) {
@ -622,8 +634,7 @@ void ReportEpgBugFixStats(bool Reset)
if (*buffer) if (*buffer)
dsyslog("%s", buffer); dsyslog("%s", buffer);
} }
if (Reset) p->hits = p->n = 0;
p->hits = p->n = 0;
} }
if (GotHits) if (GotHits)
dsyslog("====================="); dsyslog("=====================");
@ -1109,6 +1120,44 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules)
return false; return false;
} }
// --- cEpgDataWriter ---------------------------------------------------------
class cEpgDataWriter : public cThread {
protected:
virtual void Action(void);
public:
cEpgDataWriter(void);
void Perform(void);
};
cEpgDataWriter::cEpgDataWriter(void)
:cThread("epg data writer")
{
}
void cEpgDataWriter::Action(void)
{
SetPriority(19);
SetIOPriority(7);
Perform();
}
void cEpgDataWriter::Perform(void)
{
{
cSchedulesLock SchedulesLock(true, 1000);
cSchedules *s = (cSchedules *)cSchedules::Schedules(SchedulesLock);
if (s) {
time_t now = time(NULL);
for (cSchedule *p = s->First(); p; p = s->Next(p))
p->Cleanup(now);
}
}
cSchedules::Dump();
}
static cEpgDataWriter EpgDataWriter;
// --- cSchedulesLock -------------------------------------------------------- // --- cSchedulesLock --------------------------------------------------------
cSchedulesLock::cSchedulesLock(bool WriteLock, int TimeoutMs) cSchedulesLock::cSchedulesLock(bool WriteLock, int TimeoutMs)
@ -1126,7 +1175,6 @@ cSchedulesLock::~cSchedulesLock()
cSchedules cSchedules::schedules; cSchedules cSchedules::schedules;
char *cSchedules::epgDataFileName = NULL; char *cSchedules::epgDataFileName = NULL;
time_t cSchedules::lastCleanup = time(NULL);
time_t cSchedules::lastDump = time(NULL); time_t cSchedules::lastDump = time(NULL);
time_t cSchedules::modified = 0; time_t cSchedules::modified = 0;
@ -1152,28 +1200,13 @@ void cSchedules::Cleanup(bool Force)
if (Force) if (Force)
lastDump = 0; lastDump = 0;
time_t now = time(NULL); time_t now = time(NULL);
struct tm tm_r; if (now - lastDump > EPGDATAWRITEDELTA) {
struct tm *ptm = localtime_r(&now, &tm_r); if (epgDataFileName) {
if (now - lastCleanup > 3600) { if (Force)
isyslog("cleaning up schedules data"); EpgDataWriter.Perform();
cSchedulesLock SchedulesLock(true, 1000); else if (!EpgDataWriter.Active())
cSchedules *s = (cSchedules *)Schedules(SchedulesLock); EpgDataWriter.Start();
if (s) {
for (cSchedule *p = s->First(); p; p = s->Next(p))
p->Cleanup(now);
} }
lastCleanup = now;
if (ptm->tm_hour == 5)
ReportEpgBugFixStats(true);
}
if (epgDataFileName && now - lastDump > 600) {
cSafeFile f(epgDataFileName);
if (f.Open()) {
Dump(f);
f.Close();
}
else
LOG_ERROR;
lastDump = now; lastDump = now;
} }
} }
@ -1207,8 +1240,23 @@ bool cSchedules::Dump(FILE *f, const char *Prefix, eDumpMode DumpMode, time_t At
cSchedulesLock SchedulesLock; cSchedulesLock SchedulesLock;
cSchedules *s = (cSchedules *)Schedules(SchedulesLock); cSchedules *s = (cSchedules *)Schedules(SchedulesLock);
if (s) { if (s) {
cSafeFile *sf = NULL;
if (!f) {
sf = new cSafeFile(epgDataFileName);
if (sf->Open())
f = *sf;
else {
LOG_ERROR;
delete sf;
return false;
}
}
for (cSchedule *p = s->First(); p; p = s->Next(p)) for (cSchedule *p = s->First(); p; p = s->Next(p))
p->Dump(f, Prefix, DumpMode, AtTime); p->Dump(f, Prefix, DumpMode, AtTime);
if (sf) {
sf->Close();
delete sf;
}
return true; return true;
} }
return false; return false;

7
epg.h
View File

@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by * Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* *
* $Id: epg.h 2.14 2012/08/25 11:15:18 kls Exp $ * $Id: epg.h 2.15 2012/09/24 12:53:53 kls Exp $
*/ */
#ifndef __EPG_H #ifndef __EPG_H
@ -193,7 +193,6 @@ private:
cRwLock rwlock; cRwLock rwlock;
static cSchedules schedules; static cSchedules schedules;
static char *epgDataFileName; static char *epgDataFileName;
static time_t lastCleanup;
static time_t lastDump; static time_t lastDump;
static time_t modified; static time_t modified;
public: public:
@ -207,7 +206,7 @@ public:
static void Cleanup(bool Force = false); static void Cleanup(bool Force = false);
static void ResetVersions(void); static void ResetVersions(void);
static bool ClearAll(void); static bool ClearAll(void);
static bool Dump(FILE *f, const char *Prefix = "", eDumpMode DumpMode = dmAll, time_t AtTime = 0); static bool Dump(FILE *f = NULL, const char *Prefix = "", eDumpMode DumpMode = dmAll, time_t AtTime = 0);
static bool Read(FILE *f = NULL); static bool Read(FILE *f = NULL);
cSchedule *AddSchedule(tChannelID ChannelID); cSchedule *AddSchedule(tChannelID ChannelID);
const cSchedule *GetSchedule(tChannelID ChannelID) const; const cSchedule *GetSchedule(tChannelID ChannelID) const;
@ -220,7 +219,7 @@ public:
virtual void Action(void); virtual void Action(void);
}; };
void ReportEpgBugFixStats(bool Reset = false); void ReportEpgBugFixStats(bool Force = false);
class cEpgHandler : public cListObject { class cEpgHandler : public cListObject {
public: public:

6
vdr.c
View File

@ -22,7 +22,7 @@
* *
* The project's page is at http://www.tvdr.de * The project's page is at http://www.tvdr.de
* *
* $Id: vdr.c 2.39 2012/09/17 08:56:58 kls Exp $ * $Id: vdr.c 2.40 2012/09/24 12:43:04 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
@ -1295,6 +1295,8 @@ int main(int argc, char *argv[])
PluginManager.Housekeeping(); PluginManager.Housekeeping();
} }
ReportEpgBugFixStats();
// Main thread hooks of plugins: // Main thread hooks of plugins:
PluginManager.MainThreadHook(); PluginManager.MainThreadHook();
} }
@ -1331,7 +1333,7 @@ Exit:
EpgHandlers.Clear(); EpgHandlers.Clear();
PluginManager.Shutdown(true); PluginManager.Shutdown(true);
cSchedules::Cleanup(true); cSchedules::Cleanup(true);
ReportEpgBugFixStats(); ReportEpgBugFixStats(true);
if (WatchdogTimeout > 0) if (WatchdogTimeout > 0)
dsyslog("max. latency time %d seconds", MaxLatencyTime); dsyslog("max. latency time %d seconds", MaxLatencyTime);
if (LastSignal) if (LastSignal)