summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJochen Dolze <vdr@dolze.de>2011-08-05 14:02:47 +0200
committerJochen Dolze <vdr@dolze.de>2011-08-05 14:02:47 +0200
commit8f13f082303ae844d8408b78c8c8fa4c5c9b1d26 (patch)
tree2c169bdcef39d35dc4f60b7dab1004c727ffb973
parentfd38b68561f3c2b0bf2cf369cc3cc48dbca60fc8 (diff)
downloadvdr-plugin-xmltv2vdr-8f13f082303ae844d8408b78c8c8fa4c5c9b1d26.tar.gz
vdr-plugin-xmltv2vdr-8f13f082303ae844d8408b78c8c8fa4c5c9b1d26.tar.bz2
Prevent mapping deletion of an disabled channel
Added proper thread cleanup
-rw-r--r--maps.cpp42
-rw-r--r--maps.h4
-rw-r--r--parse.cpp23
-rw-r--r--parse.h4
-rw-r--r--setup.cpp35
-rw-r--r--xmltv2vdr.cpp33
-rw-r--r--xmltv2vdr.h11
7 files changed, 110 insertions, 42 deletions
diff --git a/maps.cpp b/maps.cpp
index 884a23f..be92a4c 100644
--- a/maps.cpp
+++ b/maps.cpp
@@ -187,7 +187,41 @@ void cEPGMapping::ReplaceChannels(int NumChannelIDs, tChannelID *ChannelIDs)
}
}
-void cEPGMapping::RemoveChannel(int ChannelNumber)
+void cEPGMapping::RemoveInvalidChannels()
+{
+ qsort(channelids,numchannelids,sizeof(tChannelID),compare);
+ for (int i=0; i<numchannelids; i++)
+ {
+ if (channelids[i]==tChannelID::InvalidID)
+ {
+ numchannelids--;
+ }
+ }
+}
+
+void cEPGMapping::RemoveChannel(tChannelID ChannelID, bool MarkOnly)
+{
+ bool found=false;
+ int i;
+ for (i=0; i<numchannelids; i++)
+ {
+ if (channelids[i]==ChannelID)
+ {
+ found=true;
+ break;
+ }
+ }
+ if (found)
+ {
+ channelids[i]=tChannelID::InvalidID;
+ if (!MarkOnly) {
+ qsort(channelids,numchannelids,sizeof(tChannelID),compare);
+ numchannelids--;
+ }
+ }
+}
+
+void cEPGMapping::RemoveChannel(int ChannelNumber, bool MarkOnly)
{
if (!ChannelNumber) return;
cChannel *chan=Channels.GetByNumber(ChannelNumber);
@@ -206,7 +240,9 @@ void cEPGMapping::RemoveChannel(int ChannelNumber)
if (found)
{
channelids[i]=tChannelID::InvalidID;
- qsort(channelids,numchannelids,sizeof(tChannelID),compare);
- numchannelids--;
+ if (!MarkOnly) {
+ qsort(channelids,numchannelids,sizeof(tChannelID),compare);
+ numchannelids--;
+ }
}
}
diff --git a/maps.h b/maps.h
index cf022f3..6f9fefe 100644
--- a/maps.h
+++ b/maps.h
@@ -84,7 +84,9 @@ public:
}
void ReplaceChannels(int NumChannelIDs, tChannelID *ChannelIDs);
void AddChannel(int ChannelNumber);
- void RemoveChannel(int ChannelNumber);
+ void RemoveChannel(int ChannelNumber, bool MarkOnly=false);
+ void RemoveChannel(tChannelID ChannelID, bool MarkOnly=false);
+ void RemoveInvalidChannels();
int Flags()
{
return flags;
diff --git a/parse.cpp b/parse.cpp
index cbf7a60..dc37265 100644
--- a/parse.cpp
+++ b/parse.cpp
@@ -14,6 +14,7 @@
#include <locale.h>
#include <langinfo.h>
+#include "xmltv2vdr.h"
#include "parse.h"
extern char *strcatrealloc(char *dest, const char *src);
@@ -857,7 +858,7 @@ cEPGMapping *cParse::EPGMapping(const char *ChannelName)
return NULL;
}
-int cParse::Process(char *buffer, int bufsize)
+int cParse::Process(cEPGExecutor &myExecutor,char *buffer, int bufsize)
{
if (!buffer) return 134;
if (!bufsize) return 134;
@@ -877,8 +878,19 @@ int cParse::Process(char *buffer, int bufsize)
return 141;
}
- cSchedulesLock schedulesLock(true,25000); // wait up to 25 secs for lock!
- const cSchedules *schedules = cSchedules::Schedules(schedulesLock);
+ const cSchedules *schedules=NULL;
+ int l=0;
+ while (l<300) {
+ cSchedulesLock schedulesLock(true,200); // wait up to 60 secs for lock!
+ schedules = cSchedules::Schedules(schedulesLock);
+ if (!myExecutor.StillRunning()) {
+ isyslog("xmltv2vdr: '%s' request to stop from vdr",name);
+ return 0;
+ }
+ if (schedules) break;
+ l++;
+ }
+
if (!schedules)
{
esyslog("xmltv2vdr: '%s' cannot get schedules now, trying later",name);
@@ -1045,6 +1057,11 @@ int cParse::Process(char *buffer, int bufsize)
}
}
node=node->next;
+ if (!myExecutor.StillRunning()) {
+ xmlFreeDoc(xmltv);
+ isyslog("xmltv2vdr: '%s' request to stop from vdr",name);
+ return 0;
+ }
}
xmlFreeDoc(xmltv);
return 0;
diff --git a/parse.h b/parse.h
index 2ea1912..90c24b0 100644
--- a/parse.h
+++ b/parse.h
@@ -15,6 +15,8 @@
#include "maps.h"
+class cEPGExecutor;
+
class cXMLTVEvent
{
private:
@@ -174,7 +176,7 @@ private:
public:
cParse(const char *Name, cEPGMappings *Maps, cTEXTMappings *Texts);
~cParse();
- int Process(char *buffer, int bufsize);
+ int Process(cEPGExecutor &myExecutor, char *buffer, int bufsize);
static void InitLibXML();
static void CleanupLibXML();
};
diff --git a/setup.cpp b/setup.cpp
index a722410..d30289b 100644
--- a/setup.cpp
+++ b/setup.cpp
@@ -133,12 +133,6 @@ void cMenuSetupXmltv2vdr::Output(void)
void cMenuSetupXmltv2vdr::generatesumchannellist()
{
- cStringList oldchannels;
- for (int i=0; i<channels.Size(); i++)
- {
- oldchannels.Append(strdup(channels[i]));
- }
-
channels.Clear();
for (int i=0; i<baseplugin->EPGSourceCount(); i++)
{
@@ -168,25 +162,6 @@ void cMenuSetupXmltv2vdr::generatesumchannellist()
}
}
channels.Sort();
-
- for (int i=0; i<oldchannels.Size(); i++)
- {
- if (channels.Find(oldchannels[i])==-1)
- {
- cEPGMapping *map=baseplugin->EPGMapping(oldchannels[i]);
- if (map)
- {
- map->ReplaceChannels(0,NULL);
- map->ChangeFlags(0);
- char *name=NULL;
- if (asprintf(&name,"channel.%s",map->ChannelName())!=-1)
- {
- SetupStore(name,"1;0;");
- free(name);
- }
- }
- }
- }
}
cOsdItem *cMenuSetupXmltv2vdr::newtitle(const char *s)
@@ -821,8 +796,8 @@ int cMenuSetupXmltv2vdrChannelMap::getdaysmax()
cOsdItem *cMenuSetupXmltv2vdrChannelMap::optionN(const char *s, int num)
{
- cString buffer = cString::sprintf("%s:\t%i", s, num);
- return new cOsdItem(buffer,osUnknown,false);
+ cString buffer = cString::sprintf("%s:\t%i", s, num);
+ return new cOsdItem(buffer,osUnknown,false);
}
cOsdItem *cMenuSetupXmltv2vdrChannelMap::option(const char *s, bool yesno)
@@ -851,7 +826,7 @@ void cMenuSetupXmltv2vdrChannelMap::output(void)
c1=Current();
if ((flags & OPT_APPEND)!=OPT_APPEND)
{
- Add(optionN(tr("days in advance"),1),true);
+ Add(optionN(tr("days in advance"),1),true);
Add(new cMyMenuEditBitItem(tr("short text"),&flags,USE_SHORTTEXT),true);
Add(new cMyMenuEditBitItem(tr("long text"),&flags,USE_LONGTEXT),true);
c2=Current();
@@ -897,8 +872,12 @@ void cMenuSetupXmltv2vdrChannelMap::output(void)
Add(new cOsdItem(buffer),true);
if (!hasmaps) cm=Current();
hasmaps=true;
+ } else {
+ // invalid channelid? remove from list
+ map->RemoveChannel(map->ChannelIDs()[i],true);
}
}
+ map->RemoveInvalidChannels();
if (!hasmaps)
{
Add(new cOsdItem(tr("none")),true);
diff --git a/xmltv2vdr.cpp b/xmltv2vdr.cpp
index 42be8cb..01e767b 100644
--- a/xmltv2vdr.cpp
+++ b/xmltv2vdr.cpp
@@ -11,6 +11,7 @@
#include <sys/wait.h>
#include <sys/ioctl.h>
#include "xmltv2vdr.h"
+#include "parse.h"
#include "extpipe.h"
#include "setup.h"
@@ -55,11 +56,22 @@ void cEPGExecutor::Action()
int retries=0;
while (retries<2)
{
- ret=epgs->Execute();
+ ret=epgs->Execute(*this);
if ((ret>0) && (ret<126))
{
dsyslog("xmltv2vdr: '%s' waiting 60 seconds",epgs->Name());
- sleep(60);
+ int l=0;
+ while (l<300) {
+ struct timespec req;
+ req.tv_sec=0;
+ req.tv_nsec=200000000; // 200ms
+ nanosleep(&req,NULL);
+ if (!Running()) {
+ isyslog("xmltv2vdr: '%s' request to stop from vdr",epgs->Name());
+ return;
+ }
+ l++;
+ }
retries++;
}
else
@@ -313,8 +325,9 @@ int cEPGSource::ReadOutput(char *&result, size_t &l)
return ret;
}
-int cEPGSource::Execute()
+int cEPGSource::Execute(cEPGExecutor &myExecutor)
{
+
if (!ready2parse) return false;
if (!parse) return false;
char *r_out=NULL;
@@ -416,6 +429,15 @@ int cEPGSource::Execute()
if (fds[1].revents & POLLHUP) {
fdsopen--;
}
+ if (!myExecutor.StillRunning()) {
+ int status;
+ p.Close(status);
+ if (r_out) free(r_out);
+ if (r_err) free(r_err);
+ isyslog("xmltv2vdr: '%s' request to stop from vdr",name);
+ return 0;
+ }
+
} else {
esyslog("xmltv2vdr: '%s' ERROR polling",name);
break;
@@ -433,7 +455,7 @@ int cEPGSource::Execute()
if ((!returncode) && (r_out))
{
dsyslog("xmltv2vdr: '%s' parsing output",name);
- ret=parse->Process(r_out,l_out);
+ ret=parse->Process(myExecutor,r_out,l_out);
}
else
{
@@ -459,7 +481,7 @@ int cEPGSource::Execute()
char *result=NULL;
ret=ReadOutput(result,l);
if ((!ret) && (result)) {
- ret=parse->Process(result,l);
+ ret=parse->Process(myExecutor,result,l);
}
if (result) free(result);
}
@@ -735,6 +757,7 @@ bool cPluginXmltv2vdr::Start(void)
void cPluginXmltv2vdr::Stop(void)
{
// Stop any background activities the plugin is performing.
+ epgexecutor.Stop();
removeepgsources();
removeepgmappings();
removetextmappings();
diff --git a/xmltv2vdr.h b/xmltv2vdr.h
index 1d05782..14bbf12 100644
--- a/xmltv2vdr.h
+++ b/xmltv2vdr.h
@@ -42,6 +42,8 @@ public:
class cEPGChannels : public cList<cEPGChannel> {};
+class cEPGExecutor;
+
class cEPGSource : public cListObject
{
private:
@@ -60,7 +62,7 @@ private:
public:
cEPGSource(const char *Name,const char *ConfDir,cEPGMappings *Maps,cTEXTMappings *Texts);
~cEPGSource();
- int Execute();
+ int Execute(cEPGExecutor &myExecutor);
void Store(void);
void ChangeChannelSelection(int *Selection);
cEPGChannels *ChannelList()
@@ -106,6 +108,13 @@ private:
cEPGSources *sources;
public:
cEPGExecutor(cEPGSources *Sources);
+ bool StillRunning() {
+ return Running();
+ }
+ void Stop()
+ {
+ Cancel(3);
+ }
virtual void Action();
};