diff options
author | Jochen Dolze <vdr@dolze.de> | 2011-08-05 14:02:47 +0200 |
---|---|---|
committer | Jochen Dolze <vdr@dolze.de> | 2011-08-05 14:02:47 +0200 |
commit | 8f13f082303ae844d8408b78c8c8fa4c5c9b1d26 (patch) | |
tree | 2c169bdcef39d35dc4f60b7dab1004c727ffb973 | |
parent | fd38b68561f3c2b0bf2cf369cc3cc48dbca60fc8 (diff) | |
download | vdr-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.cpp | 42 | ||||
-rw-r--r-- | maps.h | 4 | ||||
-rw-r--r-- | parse.cpp | 23 | ||||
-rw-r--r-- | parse.h | 4 | ||||
-rw-r--r-- | setup.cpp | 35 | ||||
-rw-r--r-- | xmltv2vdr.cpp | 33 | ||||
-rw-r--r-- | xmltv2vdr.h | 11 |
7 files changed, 110 insertions, 42 deletions
@@ -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--; + } } } @@ -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; @@ -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; @@ -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(); }; @@ -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(); }; |