epgache: move epg cache file name to main enigma2 settings file (config.misc.epgache_...
authorghost <andreas.monzner@multimedia-labs.de>
Thu, 4 Nov 2010 23:16:16 +0000 (00:16 +0100)
committerghost <andreas.monzner@multimedia-labs.de>
Thu, 4 Nov 2010 23:16:35 +0000 (00:16 +0100)
lib/dvb/epgcache.cpp
lib/dvb/epgcache.h
mytest.py

index 2b688c2..15248a6 100644 (file)
@@ -213,9 +213,9 @@ pthread_mutex_t eEPGCache::channel_map_lock=
 DEFINE_REF(eEPGCache)
 
 eEPGCache::eEPGCache()
 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);
 
        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
        if (!res_mgr)
                eDebug("[eEPGCache] no resource manager !!!!!!!");
        else
-       {
                res_mgr->connectChannelAdded(slot(*this,&eEPGCache::DVBChannelAdded), m_chanAddedConn);
                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));
        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()
 {
 }
 
 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)
 }
 
 void eEPGCache::DVBChannelAdded(eDVBChannel *chan)
@@ -361,8 +362,11 @@ void eEPGCache::DVBChannelRunning(iDVBChannel *chan)
                                        return;
                                }
 #endif
                                        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);
                                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);
                                        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();
 void eEPGCache::thread()
 {
        hasStarted();
+       m_running=1;
        nice(4);
        load();
        cleanLoop();
        runLoop();
        save();
        nice(4);
        load();
        cleanLoop();
        runLoop();
        save();
+       m_running=0;
 }
 
 void eEPGCache::load()
 }
 
 void eEPGCache::load()
@@ -1082,99 +1089,106 @@ void eEPGCache::load()
 
 void eEPGCache::save()
 {
 
 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)
        char *buf = realpath(m_filename, NULL);
        if (!buf)
+       {
+               eDebug("[EPGC] realpath to '%s' failed in save (%m)", m_filename);
+               fclose(f);
                return;
                return;
+       }
 
 
-       eDebug("[EPGC] store epg to '%s'", buf);
+       eDebug("[EPGC] store epg to realpath '%s'", buf);
 
        struct statfs s;
        off64_t tmp;
 
        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);
 
        }
 
        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
        // 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;
                return;
+       }
 
 
-       FILE *f = fopen(m_filename, "w");
        int cnt=0;
        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
 #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);
                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);
                        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)
 }
 
 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))
        ,isRunning(0), haveData(0)
 #ifdef ENABLE_PRIVATE_EPG
        ,startPrivateTimer(eTimer::create(ml))
index dca05a5..90aff6c 100644 (file)
@@ -177,7 +177,8 @@ class eEPGCache: public eMainloop, private eThread, public Object
                eEPGCache *cache;
                ePtr<eTimer> abortTimer, zapTimer;
                int prevChannelState;
                eEPGCache *cache;
                ePtr<eTimer> abortTimer, zapTimer;
                int prevChannelState;
-               __u8 state, isRunning, haveData;
+               int state;
+               __u8 isRunning, haveData;
                ePtr<eDVBChannel> channel;
                ePtr<eConnection> m_stateChangedConn, m_NowNextConn, m_ScheduleConn, m_ScheduleOtherConn, m_ViasatConn;
                ePtr<iDVBSectionReader> m_NowNextReader, m_ScheduleReader, m_ScheduleOtherReader, m_ViasatReader;
                ePtr<eDVBChannel> channel;
                ePtr<eConnection> m_stateChangedConn, m_NowNextConn, m_ScheduleConn, m_ScheduleOtherConn, m_ViasatConn;
                ePtr<iDVBSectionReader> m_NowNextReader, m_ScheduleReader, m_ScheduleOtherReader, m_ViasatReader;
@@ -290,6 +291,7 @@ private:
        void thread();  // thread function
 
 // called from epgcache thread
        void thread();  // thread function
 
 // called from epgcache thread
+       int m_running;
        char m_filename[1024];
        void save();
        void load();
        char m_filename[1024];
        void save();
        void load();
@@ -326,6 +328,9 @@ public:
 #endif
 
 #endif
 #endif
 
 #endif
+       // must be called once!
+       void setCacheFile(const char *filename);
+
        // called from main thread
        inline void Lock();
        inline void Unlock();
        // called from main thread
        inline void Lock();
        inline void Unlock();
index a3cfb5a..92e49ba 100755 (executable)
--- 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, \
 profile("PYTHON_START")
 
 from enigma import runMainloop, eDVBDB, eTimer, quitMainloop, \
-       getDesktop, ePythonConfigQuery, eAVSwitch, eServiceEvent
+       getDesktop, ePythonConfigQuery, eAVSwitch, eServiceEvent, \
+       eEPGCache
 from tools import *
 
 profile("LANGUAGE")
 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.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():
 
 #demo code for use of standby enter leave callbacks
 #def leaveStandby():