+ /* we do NOT handle resource conflicts here. instead, the allocateChannel
+ fails, and the application has to see why the channel is allocated
+ (and how to deallocate it). */
+class iDVBAdapter;
+
+class eDVBRegisteredFrontend: public iObject, public Object
+{
+ DECLARE_REF(eDVBRegisteredFrontend);
+ eTimer *disable;
+ void closeFrontend()
+ {
+ if (!m_inuse && m_frontend->closeFrontend()) // frontend busy
+ disable->start(60000, true); // retry close in 60secs
+ }
+public:
+ eDVBRegisteredFrontend(eDVBFrontend *fe, iDVBAdapter *adap)
+ :disable(new eTimer(eApp)), m_adapter(adap), m_frontend(fe), m_inuse(0)
+ {
+ disable = new eTimer(eApp);
+ CONNECT(disable->timeout, eDVBRegisteredFrontend::closeFrontend);
+ }
+ void dec_use()
+ {
+ if (!--m_inuse)
+ disable->start(3000, true);
+ }
+ void inc_use()
+ {
+ if (++m_inuse == 1)
+ m_frontend->openFrontend();
+ }
+ iDVBAdapter *m_adapter;
+ ePtr<eDVBFrontend> m_frontend;
+ int m_inuse;
+};
+
+struct eDVBRegisteredDemux
+{
+DECLARE_REF(eDVBRegisteredDemux);
+public:
+ iDVBAdapter *m_adapter;
+ ePtr<eDVBDemux> m_demux;
+ int m_inuse;
+ eDVBRegisteredDemux(eDVBDemux *demux, iDVBAdapter *adap): m_adapter(adap), m_demux(demux), m_inuse(0) { }
+};
+
+class eDVBAllocatedFrontend
+{
+DECLARE_REF(eDVBAllocatedFrontend);
+public:
+
+ eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe);
+ ~eDVBAllocatedFrontend();
+ eDVBFrontend &get() { return *m_fe->m_frontend; }
+ operator eDVBRegisteredFrontend*() { return m_fe; }
+ operator eDVBFrontend*() { return m_fe->m_frontend; }
+
+private:
+ eDVBRegisteredFrontend *m_fe;
+};
+
+class eDVBAllocatedDemux