- 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 159eeb2..7e441ab 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 c46bb4a..cfbff6d 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 f1f5580..35849b4 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 34c5549..bb9e268 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 136c167..d86d1ac 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 bfd3add..fb6b56f 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 */