- add eUsePtr for eDVBChannels
authorFelix Domke <tmbinc@elitedvb.net>
Tue, 12 Jul 2005 14:00:01 +0000 (14:00 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Tue, 12 Jul 2005 14:00:01 +0000 (14:00 +0000)
lib/base/smartptr.h
lib/components/scan.cpp
lib/dvb/dvb.cpp
lib/dvb/dvb.h
lib/dvb/pmt.h
lib/dvb/scan.h

index 159eeb2c0122ff43fa16786fb7dd787c20eaeb62..7e441ab2976ab67e48e67b89064a72c22fe9ec7f 100644 (file)
@@ -66,6 +66,81 @@ public:
 };
 
 
+template<class T>
+class eUsePtr
+{
+protected:
+       T *ptr;
+public:
+       T &operator*() { return *ptr; }
+       eUsePtr(): ptr(0)
+       {
+       }
+       eUsePtr(T *c): ptr(c)
+       {
+               if (c)
+               {
+                       c->AddRef();
+                       c->AddUse();
+               }
+       }
+       eUsePtr(const eUsePtr &c)
+       {
+               ptr=c.ptr;
+               if (ptr)
+               {
+                       ptr->AddRef();
+                       ptr->AddUse();
+               }
+       }
+       eUsePtr &operator=(T *c)
+       {
+               if (c)
+               {
+                       c->AddRef();
+                       c->AddUse();
+               }
+               if (ptr)
+               {
+                       ptr->ReleaseUse();
+                       ptr->Release();
+               }
+               ptr=c;
+               return *this;
+       }
+       
+       eUsePtr &operator=(eUsePtr<T> &c)
+       {
+               if (c.ptr)
+               {
+                       c.ptr->AddRef();
+                       c.ptr->AddUse();
+               }
+               if (ptr)
+               {
+                       ptr->ReleaseUse();
+                       ptr->Release();
+               }
+               ptr=c.ptr;
+               return *this;
+       }
+       
+       ~eUsePtr()
+       {
+               if (ptr)
+               {
+                       ptr->ReleaseUse();
+                       ptr->Release();
+               }
+       }
+       
+       T* grabRef() { if (!ptr) return 0; ptr->AddRef(); ptr->AddUse(); return ptr; }
+       T* &ptrref() { assert(!ptr); return ptr; }
+       T* operator->() const { assert(ptr); return ptr; }
+       operator T*() const { return this->ptr; }
+};
+
+
 
 #ifndef SWIG
 template<class T>
index c46bb4a8681bdc67c7e0bbd61d6de159433647bb..cfbff6d8be62e75528fb6d0478dd092a3fd11e30 100644 (file)
@@ -86,7 +86,7 @@ int eComponentScan::start()
        fet.hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy::HNone;
        fe->setDVBT(fet);
 #endif
-       ePtr<iDVBChannel> channel;
+       eUsePtr<iDVBChannel> channel;
 
        if (mgr->allocateRawChannel(channel))
        {
index f1f5580a6fe67510c008344fcb0cd7ed87448ca2..35849b4cfc4aff955429f8ee3d4e644f3ac75376 100644 (file)
@@ -240,7 +240,7 @@ RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
 }
 
 
-RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, ePtr<iDVBChannel> &channel)
+RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
 {
                /* first, check if a channel is already existing. */
        
@@ -289,7 +289,7 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, ePtr
        return 0;
 }
 
-RESULT eDVBResourceManager::allocateRawChannel(ePtr<iDVBChannel> &channel)
+RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel)
 {
        ePtr<eDVBAllocatedFrontend> fe;
        
@@ -383,6 +383,11 @@ void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
 {
        eDebug("fe state changed!");
        int state, ourstate = 0;
+       
+               /* if we are already in shutdown, don't change state. */
+       if (m_state == state_release)
+               return;
+       
        if (fe->getState(state))
                return;
        
@@ -408,6 +413,20 @@ void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
        }
 }
 
+void eDVBChannel::AddUse()
+{
+       ++m_use_count;
+}
+
+void eDVBChannel::ReleaseUse()
+{
+       if (!--m_use_count)
+       {
+               m_state = state_release;
+               m_stateChanged(this);
+       }
+}
+
 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid)
 {
        if (m_channel_id)
index 34c554926ddd184f49ae2de2fe14e707f14b4dcd..bb9e268991a760f5fc6e41fe47ff491f6431b24f 100644 (file)
@@ -156,8 +156,8 @@ public:
        };
        
                /* allocate channel... */
-       RESULT allocateChannel(const eDVBChannelID &channelid, ePtr<iDVBChannel> &channel);
-       RESULT allocateRawChannel(ePtr<iDVBChannel> &channel);
+       RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel);
+       RESULT allocateRawChannel(eUsePtr<iDVBChannel> &channel);
        RESULT allocatePVRChannel(int caps);
 
        RESULT connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection);
@@ -182,6 +182,11 @@ private:
        
        void frontendStateChanged(iDVBFrontend*fe);
        ePtr<eConnection> m_conn_frontendStateChanged;
+       
+               /* use count */
+       oRefCount m_use_count;
+       void AddUse();
+       void ReleaseUse();
 public:
        eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend, eDVBAllocatedDemux *demux);
        virtual ~eDVBChannel();
index 136c16730deb44b940c87a034ab741b858937773..d86d1ac93a9861a9db63da1422daa78ef6fc304a 100644 (file)
@@ -18,7 +18,7 @@ class eDVBServicePMTHandler: public Object
        eAUTable<eTable<ProgramMapTable> > m_PMT;
        eAUTable<eTable<ProgramAssociationTable> > m_PAT;
 
-       ePtr<iDVBChannel> m_channel;
+       eUsePtr<iDVBChannel> m_channel;
        ePtr<eDVBResourceManager> m_resourceManager;
        ePtr<iDVBDemux> m_demux;
        
index bfd3add99d88aabd1df9311c605bedb541728a9b..fb6b56f405cce9d0faa31b9a6042eefd1420fbde 100644 (file)
@@ -20,7 +20,7 @@ private:
        eDVBNamespace buildNamespace(eOriginalNetworkID onid, eTransportStreamID tsid, unsigned long hash);
        
                /* scan resources */    
-       ePtr<iDVBChannel> m_channel;
+       eUsePtr<iDVBChannel> m_channel;
        ePtr<iDVBDemux> m_demux;
        
                /* infrastructure */