release cached channel after 3 seconds when not needed
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Mon, 30 Jan 2006 00:20:57 +0000 (00:20 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Mon, 30 Jan 2006 00:20:57 +0000 (00:20 +0000)
lib/dvb/dvb.cpp
lib/dvb/dvb.h
lib/dvb/idvb.h

index 601e62799b7cecbaab2e2fa6a2cf4a96d36c97a6..8b442e3d28cf70d3d05bd90095f5c7964d79a083 100644 (file)
@@ -43,6 +43,7 @@ DEFINE_REF(eDVBResourceManager);
 eDVBResourceManager *eDVBResourceManager::instance;
 
 eDVBResourceManager::eDVBResourceManager()
 eDVBResourceManager *eDVBResourceManager::instance;
 
 eDVBResourceManager::eDVBResourceManager()
+       :m_releaseCachedChannelTimer(eApp)
 {
        avail = 1;
        busy = 0;
 {
        avail = 1;
        busy = 0;
@@ -63,6 +64,8 @@ eDVBResourceManager::eDVBResourceManager()
        
        eDebug("found %d adapter, %d frontends and %d demux", 
                m_adapter.size(), m_frontend.size(), m_demux.size());
        
        eDebug("found %d adapter, %d frontends and %d demux", 
                m_adapter.size(), m_frontend.size(), m_demux.size());
+
+       CONNECT(m_releaseCachedChannelTimer.timeout, eDVBResourceManager::releaseCachedChannel);
 }
 
 
 }
 
 
@@ -355,10 +358,40 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse
                return errChidNotFound;
        }
        m_cached_channel = channel = ch;
                return errChidNotFound;
        }
        m_cached_channel = channel = ch;
+       CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
 
        return 0;
 }
 
 
        return 0;
 }
 
+void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
+{
+       int state=0;
+       chan->getState(state);
+       switch (state)
+       {
+               case iDVBChannel::state_ok:
+               {
+                       eDebug("stop release channel timer");
+                       m_releaseCachedChannelTimer.stop();
+                       break;
+               }
+               case iDVBChannel::state_last_instance:
+               {
+                       eDebug("start release channel timer");
+                       m_releaseCachedChannelTimer.start(3000, true);
+                       break;
+               }
+               default: // ignore all other events
+                       break;
+       }
+}
+
+void eDVBResourceManager::releaseCachedChannel()
+{
+       eDebug("release cached channel");
+       m_cached_channel=0;
+}
+
 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
 {
        ePtr<eDVBAllocatedFrontend> fe;
 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
 {
        ePtr<eDVBAllocatedFrontend> fe;
@@ -780,7 +813,8 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
 
 void eDVBChannel::AddUse()
 {
 
 void eDVBChannel::AddUse()
 {
-       ++m_use_count;
+       if (++m_use_count > 1 && m_state == state_last_instance)
+               m_state = state_ok;
 }
 
 void eDVBChannel::ReleaseUse()
 }
 
 void eDVBChannel::ReleaseUse()
@@ -790,6 +824,11 @@ void eDVBChannel::ReleaseUse()
                m_state = state_release;
                m_stateChanged(this);
        }
                m_state = state_release;
                m_stateChanged(this);
        }
+       else if (m_use_count == 1)
+       {
+               m_state = state_last_instance;
+               m_stateChanged(this);
+       }
 }
 
 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
 }
 
 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
index 0e449144462132ee558f41cdc41d78a96e4a39f9..15e27536cef9f10d1be3e30e06a72b37144d68e9 100644 (file)
@@ -117,13 +117,11 @@ private:
        eSmartPtrList<eDVBDemux>    m_demux;
 };
 
        eSmartPtrList<eDVBDemux>    m_demux;
 };
 
-class eDVBResourceManager: public iObject
+class eDVBResourceManager: public iObject, public Object
 {
        DECLARE_REF(eDVBResourceManager);
        int avail, busy;
 
 {
        DECLARE_REF(eDVBResourceManager);
        int avail, busy;
 
-       eUsePtr<iDVBChannel> m_cached_channel;
-
        eSmartPtrList<iDVBAdapter> m_adapter;
        
        eSmartPtrList<eDVBRegisteredDemux> m_demux;
        eSmartPtrList<iDVBAdapter> m_adapter;
        
        eSmartPtrList<eDVBRegisteredDemux> m_demux;
@@ -167,6 +165,11 @@ class eDVBResourceManager: public iObject
        Signal1<void,eDVBChannel*> m_channelAdded;
 
        bool canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm);
        Signal1<void,eDVBChannel*> m_channelAdded;
 
        bool canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm);
+
+       eUsePtr<iDVBChannel> m_cached_channel;
+       eTimer m_releaseCachedChannelTimer;
+       void DVBChannelStateChanged(iDVBChannel*);
+       void releaseCachedChannel();
 public:
        eDVBResourceManager();
        virtual ~eDVBResourceManager();
 public:
        eDVBResourceManager();
        virtual ~eDVBResourceManager();
@@ -196,6 +199,7 @@ public:
 class eDVBChannel: public iDVBPVRChannel, public iFilePushScatterGather, public Object
 {
        DECLARE_REF(eDVBChannel);
 class eDVBChannel: public iDVBPVRChannel, public iFilePushScatterGather, public Object
 {
        DECLARE_REF(eDVBChannel);
+       friend class eDVBResourceManager;
 public:
        eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend);
        virtual ~eDVBChannel();
 public:
        eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend);
        virtual ~eDVBChannel();
index f20de1900d2b726f793fe4a61796d132bd4ed6eb..eacc49290bf5091f1d662cd362843a74d903820f 100644 (file)
@@ -392,6 +392,7 @@ public:
                state_failed,      /* tuning failed. */
                state_unavailable, /* currently unavailable, will be back without further interaction */
                state_ok,          /* ok */
                state_failed,      /* tuning failed. */
                state_unavailable, /* currently unavailable, will be back without further interaction */
                state_ok,          /* ok */
+               state_last_instance, /* just one reference to this channel is left */
                state_release      /* channel is being shut down. */
        };
        
                state_release      /* channel is being shut down. */
        };