From 7fd4241a1d7b8d7c36385860b24882636517473b Mon Sep 17 00:00:00 2001 From: ghost Date: Fri, 5 Nov 2010 00:16:16 +0100 Subject: [PATCH] epgache: move epg cache file name to main enigma2 settings file (config.misc.epgache_filename) --- lib/dvb/epgcache.cpp | 206 +++++++++++++++++++++++++++------------------------ lib/dvb/epgcache.h | 7 +- mytest.py | 6 +- 3 files changed, 121 insertions(+), 98 deletions(-) diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp index 2b688c2..15248a6 100644 --- a/lib/dvb/epgcache.cpp +++ b/lib/dvb/epgcache.cpp @@ -213,9 +213,9 @@ pthread_mutex_t eEPGCache::channel_map_lock= DEFINE_REF(eEPGCache) eEPGCache::eEPGCache() - :messages(this,1), cleanTimer(eTimer::create(this))//, paused(0) + :messages(this,1), cleanTimer(eTimer::create(this)), m_running(0)//, paused(0) { - eDebug("[EPGC] Initialized EPGCache"); + eDebug("[EPGC] Initialized EPGCache (wait for setCacheFile call now)"); CONNECT(messages.recv_msg, eEPGCache::gotMessage); CONNECT(eDVBLocalTimeHandler::getInstance()->m_timeUpdated, eEPGCache::timeUpdated); @@ -226,46 +226,47 @@ eEPGCache::eEPGCache() if (!res_mgr) eDebug("[eEPGCache] no resource manager !!!!!!!"); else - { res_mgr->connectChannelAdded(slot(*this,&eEPGCache::DVBChannelAdded), m_chanAddedConn); - if (eDVBLocalTimeHandler::getInstance()->ready()) - timeUpdated(); - } - instance=this; + instance=this; memset(m_filename, 0, sizeof(m_filename)); +} - FILE *f = fopen("/etc/enigma2/epg.dat.src", "r"); - if (f) +void eEPGCache::setCacheFile(const char *path) +{ + if (!strlen(m_filename)) { - int rd = fread(m_filename, 1, 255, f); - if (rd > 0) - { - m_filename[rd] = 0; - char *p=strchr(m_filename, '\n'); - if (p) - m_filename[p-m_filename] = 0; - p=strchr(m_filename, '\t'); - if (p) - m_filename[p-m_filename] = 0; - } - fclose(f); + strncpy(m_filename, path, 1024); + eDebug("[EPGC] setCacheFile read/write epg data from/to '%s'", m_filename); + if (eDVBLocalTimeHandler::getInstance()->ready()) + timeUpdated(); } - - if (!strlen(m_filename)) - strcpy(m_filename, "/hdd/epg.dat"); - - eDebug("[EPGC] read/write epg data from/to '%s'", m_filename); + else + eDebug("[EPGC] setCacheFile already called... ignore '%s'", path); } void eEPGCache::timeUpdated() { - if (!sync()) + if (strlen(m_filename)) { - eDebug("[EPGC] time updated.. start EPG Mainloop"); - run(); - } else - messages.send(Message(Message::timeChanged)); + if (!sync()) + { + eDebug("[EPGC] time updated.. start EPG Mainloop"); + run(); + singleLock s(channel_map_lock); + channelMapIterator it = m_knownChannels.begin(); + for (; it != m_knownChannels.end(); ++it) + { + if (it->second->state == -1) { + it->second->state=0; + messages.send(Message(Message::startChannel, it->second)); + } + } + } else + messages.send(Message(Message::timeChanged)); + } + else + eDebug("[EPGC] time updated.. but cache file not set yet.. dont start epg!!"); } void eEPGCache::DVBChannelAdded(eDVBChannel *chan) @@ -361,8 +362,11 @@ void eEPGCache::DVBChannelRunning(iDVBChannel *chan) return; } #endif - messages.send(Message(Message::startChannel, chan)); - // -> gotMessage -> changedService + if (m_running) { + data.state=0; + messages.send(Message(Message::startChannel, chan)); + // -> gotMessage -> changedService + } } } } @@ -389,7 +393,8 @@ void eEPGCache::DVBChannelStateChanged(iDVBChannel *chan) case iDVBChannel::state_release: { eDebug("[eEPGCache] remove channel %p", chan); - messages.send(Message(Message::leaveChannel, chan)); + if (it->second->state >= 0) + messages.send(Message(Message::leaveChannel, chan)); pthread_mutex_lock(&it->second->channel_active); singleLock s(channel_map_lock); m_knownChannels.erase(it); @@ -977,11 +982,13 @@ void eEPGCache::gotMessage( const Message &msg ) void eEPGCache::thread() { hasStarted(); + m_running=1; nice(4); load(); cleanLoop(); runLoop(); save(); + m_running=0; } void eEPGCache::load() @@ -1082,99 +1089,106 @@ void eEPGCache::load() void eEPGCache::save() { + /* create empty file */ + FILE *f = fopen(m_filename, "w"); + + if (!f) + { + eDebug("[EPGC] couldn't save epg data to '%s'(%m)", m_filename); + return; + } + char *buf = realpath(m_filename, NULL); if (!buf) + { + eDebug("[EPGC] realpath to '%s' failed in save (%m)", m_filename); + fclose(f); return; + } - eDebug("[EPGC] store epg to '%s'", buf); + eDebug("[EPGC] store epg to realpath '%s'", buf); struct statfs s; off64_t tmp; - if (statfs(buf, &s)<0) - tmp=0; - else - { - tmp=s.f_blocks; - tmp*=s.f_bsize; + if (statfs(buf, &s) < 0) { + eDebug("[EPGC] statfs '%s' failed in save (%m)", buf); + fclose(f); + return; } free(buf); - // prevent writes to builtin flash - if ( tmp < 1024*1024*50 ) // storage size < 50MB - return; - // check for enough free space on storage tmp=s.f_bfree; tmp*=s.f_bsize; if ( tmp < (eventData::CacheSize*12)/10 ) // 20% overhead + { + eDebug("[EPGC] not enough free space at path '%s' %lld bytes availd but %d needed", buf, tmp, (eventData::CacheSize*12)/10); + fclose(f); return; + } - FILE *f = fopen(m_filename, "w"); int cnt=0; - if ( f ) - { - unsigned int magic = 0x98765432; - fwrite( &magic, sizeof(int), 1, f); - const char *text = "UNFINISHED_V7"; - fwrite( text, 13, 1, f ); - int size = eventDB.size(); - fwrite( &size, sizeof(int), 1, f ); - for (eventCache::iterator service_it(eventDB.begin()); service_it != eventDB.end(); ++service_it) - { - timeMap &timemap = service_it->second.second; - fwrite( &service_it->first, sizeof(uniqueEPGKey), 1, f); - size = timemap.size(); - fwrite( &size, sizeof(int), 1, f); - for (timeMap::iterator time_it(timemap.begin()); time_it != timemap.end(); ++time_it) - { - __u8 len = time_it->second->ByteSize; - fwrite( &time_it->second->type, sizeof(__u8), 1, f ); - fwrite( &len, sizeof(__u8), 1, f); - fwrite( time_it->second->EITdata, len, 1, f); - ++cnt; - } + unsigned int magic = 0x98765432; + fwrite( &magic, sizeof(int), 1, f); + const char *text = "UNFINISHED_V7"; + fwrite( text, 13, 1, f ); + int size = eventDB.size(); + fwrite( &size, sizeof(int), 1, f ); + for (eventCache::iterator service_it(eventDB.begin()); service_it != eventDB.end(); ++service_it) + { + timeMap &timemap = service_it->second.second; + fwrite( &service_it->first, sizeof(uniqueEPGKey), 1, f); + size = timemap.size(); + fwrite( &size, sizeof(int), 1, f); + for (timeMap::iterator time_it(timemap.begin()); time_it != timemap.end(); ++time_it) + { + __u8 len = time_it->second->ByteSize; + fwrite( &time_it->second->type, sizeof(__u8), 1, f ); + fwrite( &len, sizeof(__u8), 1, f); + fwrite( time_it->second->EITdata, len, 1, f); + ++cnt; } - eDebug("[EPGC] %d events written to %s", cnt, m_filename); - eventData::save(f); + } + eDebug("[EPGC] %d events written to %s", cnt, m_filename); + eventData::save(f); #ifdef ENABLE_PRIVATE_EPG - const char* text3 = "PRIVATE_EPG"; - fwrite( text3, 11, 1, f ); - size = content_time_tables.size(); + const char* text3 = "PRIVATE_EPG"; + fwrite( text3, 11, 1, f ); + size = content_time_tables.size(); + fwrite( &size, sizeof(int), 1, f); + for (contentMaps::iterator a = content_time_tables.begin(); a != content_time_tables.end(); ++a) + { + contentMap &content_time_table = a->second; + fwrite( &a->first, sizeof(uniqueEPGKey), 1, f); + int size = content_time_table.size(); fwrite( &size, sizeof(int), 1, f); - for (contentMaps::iterator a = content_time_tables.begin(); a != content_time_tables.end(); ++a) + for (contentMap::iterator i = content_time_table.begin(); i != content_time_table.end(); ++i ) { - contentMap &content_time_table = a->second; - fwrite( &a->first, sizeof(uniqueEPGKey), 1, f); - int size = content_time_table.size(); + int size = i->second.size(); + fwrite( &i->first, sizeof(int), 1, f); fwrite( &size, sizeof(int), 1, f); - for (contentMap::iterator i = content_time_table.begin(); i != content_time_table.end(); ++i ) + for ( contentTimeMap::iterator it(i->second.begin()); + it != i->second.end(); ++it ) { - int size = i->second.size(); - fwrite( &i->first, sizeof(int), 1, f); - fwrite( &size, sizeof(int), 1, f); - for ( contentTimeMap::iterator it(i->second.begin()); - it != i->second.end(); ++it ) - { - fwrite( &it->first, sizeof(time_t), 1, f); - fwrite( &it->second.first, sizeof(time_t), 1, f); - fwrite( &it->second.second, sizeof(__u16), 1, f); - } + fwrite( &it->first, sizeof(time_t), 1, f); + fwrite( &it->second.first, sizeof(time_t), 1, f); + fwrite( &it->second.second, sizeof(__u16), 1, f); } } -#endif - // write version string after binary data - // has been written to disk. - fsync(fileno(f)); - fseek(f, sizeof(int), SEEK_SET); - fwrite("ENIGMA_EPG_V7", 13, 1, f); - fclose(f); } +#endif + // write version string after binary data + // has been written to disk. + fsync(fileno(f)); + fseek(f, sizeof(int), SEEK_SET); + fwrite("ENIGMA_EPG_V7", 13, 1, f); + fclose(f); } eEPGCache::channel_data::channel_data(eEPGCache *ml) :cache(ml) - ,abortTimer(eTimer::create(ml)), zapTimer(eTimer::create(ml)), state(0) + ,abortTimer(eTimer::create(ml)), zapTimer(eTimer::create(ml)), state(-1) ,isRunning(0), haveData(0) #ifdef ENABLE_PRIVATE_EPG ,startPrivateTimer(eTimer::create(ml)) diff --git a/lib/dvb/epgcache.h b/lib/dvb/epgcache.h index dca05a5..90aff6c 100644 --- a/lib/dvb/epgcache.h +++ b/lib/dvb/epgcache.h @@ -177,7 +177,8 @@ class eEPGCache: public eMainloop, private eThread, public Object eEPGCache *cache; ePtr abortTimer, zapTimer; int prevChannelState; - __u8 state, isRunning, haveData; + int state; + __u8 isRunning, haveData; ePtr channel; ePtr m_stateChangedConn, m_NowNextConn, m_ScheduleConn, m_ScheduleOtherConn, m_ViasatConn; ePtr m_NowNextReader, m_ScheduleReader, m_ScheduleOtherReader, m_ViasatReader; @@ -290,6 +291,7 @@ private: void thread(); // thread function // called from epgcache thread + int m_running; char m_filename[1024]; void save(); void load(); @@ -326,6 +328,9 @@ public: #endif #endif + // must be called once! + void setCacheFile(const char *filename); + // called from main thread inline void Lock(); inline void Unlock(); diff --git a/mytest.py b/mytest.py index a3cfb5a..92e49ba 100755 --- a/mytest.py +++ b/mytest.py @@ -10,7 +10,8 @@ from Tools.Profile import profile, profile_final profile("PYTHON_START") from enigma import runMainloop, eDVBDB, eTimer, quitMainloop, \ - getDesktop, ePythonConfigQuery, eAVSwitch, eServiceEvent + getDesktop, ePythonConfigQuery, eAVSwitch, eServiceEvent, \ + eEPGCache from tools import * profile("LANGUAGE") @@ -55,6 +56,9 @@ config.misc.isNextRecordTimerAfterEventActionAuto = ConfigYesNo(default=False) config.misc.useTransponderTime = ConfigYesNo(default=True) config.misc.startCounter = ConfigInteger(default=0) # number of e2 starts... config.misc.standbyCounter = NoSave(ConfigInteger(default=0)) # number of standby +config.misc.epgcache_filename = ConfigText(default = "/hdd/epg.dat") + +eEPGCache.getInstance().setCacheFile(config.misc.epgcache_filename.value) #demo code for use of standby enter leave callbacks #def leaveStandby(): -- 2.7.4