Show
Ignore:
Timestamp:
05/11/08 15:04:25 (16 years ago)
Author:
ppalmers
Message:

make dbus server handle busresets cleanly (fixes #102)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/support/dbus/control-interface.xml

    r998 r1163  
    2525          <arg type="s" name="name" direction="out"/> 
    2626      </method> 
     27      <signal name="Updated"></signal> 
    2728  </interface> 
    2829 
  • trunk/libffado/support/dbus/controlserver.cpp

    r1158 r1163  
    2727#include "libcontrol/MatrixMixer.h" 
    2828#include "libutil/Time.h" 
     29#include "libutil/PosixMutex.h" 
    2930 
    3031namespace DBusControl { 
     
    3334 
    3435// --- Element 
    35 Element::Element( DBus::Connection& connection, std::string p, Control::Element &slave) 
     36Element::Element( DBus::Connection& connection, std::string p, Element* parent, Control::Element &slave) 
    3637: DBus::ObjectAdaptor(connection, p) 
    37 , m_Slave(slave) 
     38, m_Parent(parent) 
     39, m_Slave(slave) 
     40, m_UpdateLock( NULL ) 
    3841{ 
    3942    debugOutput( DEBUG_LEVEL_VERBOSE, "Created Element on '%s'\n", 
    4043                 path().c_str() ); 
     44    // allocate a lock 
     45    if(parent == NULL) { 
     46        m_UpdateLock = new Util::PosixMutex(); 
     47    } else { 
     48        m_UpdateLock = NULL; 
     49    } 
     50    // set verbose level AFTER allocating the lock 
    4151    setVerboseLevel(m_Slave.getVerboseLevel()); 
     52} 
     53 
     54void Element::setVerboseLevel(int i) 
     55{ 
     56    setDebugLevel(i); 
     57    if(m_UpdateLock) m_UpdateLock->setVerboseLevel(i); 
     58} 
     59 
     60void 
     61Element::Lock() 
     62{ 
     63    if(m_Parent) { 
     64        m_Parent->Lock(); 
     65    } else { 
     66        m_UpdateLock->Lock(); 
     67    } 
     68} 
     69 
     70void 
     71Element::Unlock() 
     72{ 
     73    if(m_Parent) { 
     74        m_Parent->Unlock(); 
     75    } else { 
     76        m_UpdateLock->Unlock(); 
     77    } 
     78} 
     79 
     80Util::Mutex* 
     81Element::getLock() 
     82{ 
     83    if(m_Parent) { 
     84        return m_Parent->getLock(); 
     85    } else { 
     86        return m_UpdateLock; 
     87    } 
    4288} 
    4389 
     
    67113 
    68114// --- Container 
    69 Container::Container( DBus::Connection& connection, std::string p, Control::Container &slave) 
    70 : Element(connection, p, slave) 
     115Container::Container( DBus::Connection& connection, std::string p, Element* parent, Control::Container &slave) 
     116: Element(connection, p, parent, slave) 
    71117, m_Slave(slave) 
    72118{ 
     
    74120                 path().c_str() ); 
    75121 
    76     // add children for the slave container 
    77     const Control::ElementVector elements = slave.getElementVector(); 
    78     for ( Control::ConstElementVectorIterator it = elements.begin(); 
    79       it != elements.end(); 
    80       ++it ) 
    81     { 
    82         Element *e=createHandler(*(*it)); 
    83         if (e) { 
    84             m_Children.push_back(e); 
    85         } else { 
    86             debugWarning("Failed to create handler for Control::Element %s\n", 
    87                 (*it)->getName().c_str()); 
     122    setDebugLevel(slave.getVerboseLevel()); 
     123 
     124    // register an update signal handler 
     125    m_updateFunctor = new MemberSignalFunctor< Container*, 
     126                      void (Container::*)(int) > 
     127                      ( this, &Container::updated, (int)Control::Container::eS_Updated ); 
     128    if(m_updateFunctor) { 
     129        if(!slave.addSignalHandler(m_updateFunctor)) { 
     130            debugWarning("Could not add update signal functor\n"); 
    88131        } 
    89     } 
    90     slave.releaseElementVector(); 
     132    } else { 
     133        debugWarning("Could not create update signal functor\n"); 
     134    } 
     135 
     136    // build the initial tree 
     137    m_Slave = slave; 
     138    updateTree(); 
    91139} 
    92140 
    93141Container::~Container() { 
     142    debugOutput( DEBUG_LEVEL_VERBOSE, "Deleting Container on '%s'\n", 
     143                 path().c_str() ); 
     144    if(m_updateFunctor) { 
     145        if(!m_Slave.remSignalHandler(m_updateFunctor)) { 
     146            debugWarning("Could not remove update signal functor\n"); 
     147        } 
     148    } 
     149    delete m_updateFunctor; 
     150 
    94151    for ( ElementVectorIterator it = m_Children.begin(); 
    95152      it != m_Children.end(); 
     
    97154    { 
    98155        delete (*it); 
     156    } 
     157} 
     158 
     159void 
     160Container::setVerboseLevel(int i) 
     161{ 
     162    for ( ElementVectorIterator it = m_Children.begin(); 
     163      it != m_Children.end(); 
     164      ++it ) 
     165    { 
     166        (*it)->setVerboseLevel(i); 
    99167    } 
    100168} 
     
    117185    } else return ""; 
    118186} 
    119  
     187//     Util::MutexLockHelper lock(*m_access_lock); 
     188 
     189// NOTE: call with access lock held! 
     190void 
     191Container::updateTree() 
     192
     193    bool something_changed = false; 
     194    debugOutput( DEBUG_LEVEL_VERBOSE, "Updating tree...\n"); 
     195    debugOutput( DEBUG_LEVEL_VERBOSE, "Add handlers for elements...\n"); 
     196    // add handlers for the slaves that don't have one yet 
     197    const Control::ElementVector elements = m_Slave.getElementVector(); 
     198    for ( Control::ConstElementVectorIterator it = elements.begin(); 
     199      it != elements.end(); 
     200      ++it ) 
     201    { 
     202        Element *e = findElementForControl((*it)); 
     203        if(e == NULL) { // element not in tree 
     204            e = createHandler(this, *(*it)); 
     205            if (e) { 
     206                e->setVerboseLevel(getDebugLevel()); 
     207                m_Children.push_back(e); 
     208                debugOutput( DEBUG_LEVEL_VERBOSE, "Created handler %p for Control::Element %s...\n", 
     209                            e, (*it)->getName().c_str()); 
     210                something_changed = true; 
     211            } else { 
     212                debugWarning("Failed to create handler for Control::Element %s\n", 
     213                    (*it)->getName().c_str()); 
     214            } 
     215        } else { 
     216            // element already present 
     217            debugOutput( DEBUG_LEVEL_VERBOSE, "Already have handler (%p) for Control::Element %s...\n", 
     218                         e, (*it)->getName().c_str()); 
     219        } 
     220    } 
     221 
     222    debugOutput( DEBUG_LEVEL_VERBOSE, "Remove handlers without element...\n"); 
     223    std::vector<Element *> to_remove; 
     224    // remove handlers that don't have a slave anymore 
     225    for ( ElementVectorIterator it = m_Children.begin(); 
     226      it != m_Children.end(); 
     227      ++it ) 
     228    { 
     229        Element *e = *it; 
     230        bool found = false; 
     231        for ( Control::ConstElementVectorIterator it2 = elements.begin(); 
     232              it2 != elements.end(); 
     233              ++it2 ) 
     234        { 
     235            if(&(e)->m_Slave == *it2) { 
     236                found = true; 
     237                debugOutput( DEBUG_LEVEL_VERBOSE, "Slave for handler %p at %s is present: Control::Element %s...\n", 
     238                            e, e->path().c_str(), (*it)->getName().c_str()); 
     239                break; 
     240            } 
     241        } 
     242 
     243        if (!found) { 
     244            debugOutput(DEBUG_LEVEL_VERBOSE,  
     245                        "going to remove handler %p on path %s since slave is gone\n", 
     246                        e, e->path().c_str()); 
     247            // can't remove while iterating 
     248            to_remove.push_back(e); 
     249            something_changed = true; 
     250        } 
     251    } 
     252    // do the actual remove 
     253    while(to_remove.size()) { 
     254        Element * e = *(to_remove.begin()); 
     255        removeElement(e); 
     256        to_remove.erase(to_remove.begin()); 
     257    } 
     258    m_Slave.releaseElementVector(); 
     259 
     260    if(something_changed) { 
     261        debugOutput(DEBUG_LEVEL_VERBOSE,  
     262                    "send dbus signal for path %s since something changed\n", 
     263                    path().c_str()); 
     264        // send a dbus signal 
     265        Updated(); 
     266    } 
     267
     268 
     269void 
     270Container::removeElement(Element *e) 
     271
     272    debugOutput(DEBUG_LEVEL_VERBOSE,  
     273                "removing handler %p on path %s\n", 
     274                path().c_str(), e); 
     275    for ( ElementVectorIterator it = m_Children.begin(); 
     276      it != m_Children.end(); 
     277      ++it ) 
     278    { 
     279        if(*it == e) { 
     280            m_Children.erase(it); 
     281            delete e; 
     282            return; 
     283        } 
     284    } 
     285    debugError("BUG: Element %p not found!\n", e); 
     286
     287 
     288// NOTE: call with access lock held! 
     289Element * 
     290Container::findElementForControl(Control::Element *e) 
     291
     292    for ( ElementVectorIterator it = m_Children.begin(); 
     293      it != m_Children.end(); 
     294      ++it ) 
     295    { 
     296        if(&(*it)->m_Slave == e) return (*it); 
     297    } 
     298    return NULL; 
     299
     300 
     301void 
     302Container::updated(int new_nb_elements) 
     303
     304    debugOutput( DEBUG_LEVEL_VERBOSE, "Got updated signal, new count='%d'\n", 
     305                 new_nb_elements ); 
     306    // we lock the tree first 
     307    Lock(); 
     308    // update our tree 
     309    updateTree(); 
     310    Unlock(); 
     311
    120312 
    121313/** 
     
    123315 */ 
    124316Element * 
    125 Container::createHandler(Control::Element& e) { 
     317Container::createHandler(Element *parent, Control::Element& e) { 
    126318    debugOutput( DEBUG_LEVEL_VERBOSE, "Creating handler for '%s'\n", 
    127319                 e.getName().c_str() ); 
     
    131323         
    132324        return new Container(conn(), std::string(path()+"/"+e.getName()),  
    133             *dynamic_cast<Control::Container *>(&e)); 
     325            parent, *dynamic_cast<Control::Container *>(&e)); 
    134326    } 
    135327     
     
    138330         
    139331        return new Continuous(conn(), std::string(path()+"/"+e.getName()), 
    140             *dynamic_cast<Control::Continuous *>(&e)); 
     332            parent, *dynamic_cast<Control::Continuous *>(&e)); 
    141333    } 
    142334     
     
    145337         
    146338        return new Discrete(conn(), std::string(path()+"/"+e.getName()), 
    147             *dynamic_cast<Control::Discrete *>(&e)); 
     339            parent, *dynamic_cast<Control::Discrete *>(&e)); 
    148340    } 
    149341     
     
    152344         
    153345        return new Text(conn(), std::string(path()+"/"+e.getName()), 
    154             *dynamic_cast<Control::Text *>(&e)); 
     346            parent, *dynamic_cast<Control::Text *>(&e)); 
    155347    } 
    156348 
     
    159351         
    160352        return new Register(conn(), std::string(path()+"/"+e.getName()), 
    161             *dynamic_cast<Control::Register *>(&e)); 
     353            parent, *dynamic_cast<Control::Register *>(&e)); 
    162354    } 
    163355 
     
    168360         
    169361        return new AttributeEnum(conn(), std::string(path()+"/"+e.getName()), 
    170             *dynamic_cast<Control::AttributeEnum *>(&e)); 
     362            parent, *dynamic_cast<Control::AttributeEnum *>(&e)); 
    171363    } 
    172364     
     
    175367         
    176368        return new Enum(conn(), std::string(path()+"/"+e.getName()), 
    177             *dynamic_cast<Control::Enum *>(&e)); 
     369            parent, *dynamic_cast<Control::Enum *>(&e)); 
    178370    } 
    179371     
     
    182374         
    183375        return new ConfigRomX(conn(), std::string(path()+"/"+e.getName()), 
    184             *dynamic_cast<ConfigRom *>(&e)); 
     376            parent, *dynamic_cast<ConfigRom *>(&e)); 
    185377    } 
    186378     
     
    189381         
    190382        return new MatrixMixer(conn(), std::string(path()+"/"+e.getName()), 
    191             *dynamic_cast<Control::MatrixMixer *>(&e)); 
     383            parent, *dynamic_cast<Control::MatrixMixer *>(&e)); 
    192384    } 
    193385     
    194386    debugOutput( DEBUG_LEVEL_VERBOSE, "Source is a Control::Element\n"); 
    195     return new Element(conn(), std::string(path()+"/"+e.getName()), e); 
     387    return new Element(conn(), std::string(path()+"/"+e.getName()), parent, e); 
    196388} 
    197389 
    198390// --- Continuous 
    199391 
    200 Continuous::Continuous( DBus::Connection& connection, std::string p, Control::Continuous &slave) 
    201 : Element(connection, p, slave) 
     392Continuous::Continuous( DBus::Connection& connection, std::string p, Element* parent, Control::Continuous &slave) 
     393: Element(connection, p, parent, slave) 
    202394, m_Slave(slave) 
    203395{ 
     
    264456// --- Discrete 
    265457 
    266 Discrete::Discrete( DBus::Connection& connection, std::string p, Control::Discrete &slave) 
    267 : Element(connection, p, slave) 
     458Discrete::Discrete( DBus::Connection& connection, std::string p, Element* parent, Control::Discrete &slave) 
     459: Element(connection, p, parent, slave) 
    268460, m_Slave(slave) 
    269461{ 
     
    314506// --- Text 
    315507 
    316 Text::Text( DBus::Connection& connection, std::string p, Control::Text &slave) 
    317 : Element(connection, p, slave) 
     508Text::Text( DBus::Connection& connection, std::string p, Element* parent, Control::Text &slave) 
     509: Element(connection, p, parent, slave) 
    318510, m_Slave(slave) 
    319511{ 
     
    344536// --- Register 
    345537 
    346 Register::Register( DBus::Connection& connection, std::string p, Control::Register &slave) 
    347 : Element(connection, p, slave) 
     538Register::Register( DBus::Connection& connection, std::string p, Element* parent, Control::Register &slave) 
     539: Element(connection, p, parent, slave) 
    348540, m_Slave(slave) 
    349541{ 
     
    374566// --- Enum 
    375567 
    376 Enum::Enum( DBus::Connection& connection, std::string p, Control::Enum &slave) 
    377 : Element(connection, p, slave) 
     568Enum::Enum( DBus::Connection& connection, std::string p, Element* parent, Control::Enum &slave) 
     569: Element(connection, p, parent, slave) 
    378570, m_Slave(slave) 
    379571{ 
     
    414606 
    415607// --- AttributeEnum 
    416 AttributeEnum::AttributeEnum( DBus::Connection& connection, std::string p, Control::AttributeEnum &slave) 
    417 : Element(connection, p, slave) 
     608AttributeEnum::AttributeEnum( DBus::Connection& connection, std::string p, Element* parent, Control::AttributeEnum &slave) 
     609: Element(connection, p, parent, slave) 
    418610, m_Slave(slave) 
    419611{ 
     
    479671// --- ConfigRom 
    480672 
    481 ConfigRomX::ConfigRomX( DBus::Connection& connection, std::string p, ConfigRom &slave) 
    482 : Element(connection, p, slave) 
     673ConfigRomX::ConfigRomX( DBus::Connection& connection, std::string p, Element* parent, ConfigRom &slave) 
     674: Element(connection, p, parent, slave) 
    483675, m_Slave(slave) 
    484676{ 
     
    525717// --- MatrixMixer 
    526718 
    527 MatrixMixer::MatrixMixer( DBus::Connection& connection, std::string p, Control::MatrixMixer &slave) 
    528 : Element(connection, p, slave) 
     719MatrixMixer::MatrixMixer( DBus::Connection& connection, std::string p, Element* parent, Control::MatrixMixer &slave) 
     720: Element(connection, p, parent, slave) 
    529721, m_Slave(slave) 
    530722{ 
  • trunk/libffado/support/dbus/controlserver.h

    r1158 r1163  
    3333#include "libcontrol/BasicElements.h" 
    3434#include "libieee1394/configrom.h" 
     35#include "libutil/Mutex.h" 
    3536 
    3637namespace Control { 
     
    3940 
    4041namespace DBusControl { 
     42 
     43class Element; 
     44class Container; 
     45 
     46template< typename CalleePtr, typename MemFunPtr > 
     47class MemberSignalFunctor 
     48    : public Control::SignalFunctor 
     49{ 
     50public: 
     51    MemberSignalFunctor( const CalleePtr& pCallee, 
     52            MemFunPtr pMemFun, 
     53            int pSignalId) 
     54        : Control::SignalFunctor( pSignalId ) 
     55        , m_pCallee( pCallee ) 
     56        , m_pMemFun( pMemFun ) 
     57        {} 
     58 
     59    virtual ~MemberSignalFunctor() 
     60        {} 
     61 
     62    virtual void operator() (int value) 
     63        { 
     64            ( ( *m_pCallee ).*m_pMemFun )(value); 
     65        } 
     66private: 
     67    CalleePtr  m_pCallee; 
     68    MemFunPtr  m_pMemFun; 
     69}; 
    4170 
    4271class Element 
     
    4574, public DBus::ObjectAdaptor 
    4675{ 
     76friend class Container; // This should not be necessary since Container derives from Element 
    4777public: 
    4878 
    4979    Element( DBus::Connection& connection, 
    50              std::string p, 
     80             std::string p, Element *, 
    5181             Control::Element &slave ); 
    5282 
     
    5686    DBus::String getDescription( ); 
    5787 
    58     void setVerboseLevel(int i) {setDebugLevel(i);}; 
    59 private: 
    60     Control::Element &m_Slave; 
    61  
     88    void setVerboseLevel(int i); 
     89 
     90protected: 
     91    void Lock(); 
     92    void Unlock(); 
     93    Util::Mutex* getLock(); 
     94 
     95    Element *           m_Parent; 
     96    Control::Element &  m_Slave; 
     97private: 
     98    Util::Mutex*        m_UpdateLock; 
    6299protected: 
    63100    DECLARE_DEBUG_MODULE; 
     
    73110public: 
    74111    Container( DBus::Connection& connection, 
    75                   std::string p, 
     112                  std::string p, Element *, 
    76113                  Control::Container &slave ); 
    77114    virtual ~Container(); 
    78      
    79     Element *createHandler(Control::Element& e); 
    80115 
    81116    DBus::Int32 getNbElements( ); 
    82117    DBus::String getElementName( const DBus::Int32& ); 
    83118 
    84 private: 
    85     Control::Container &m_Slave; 
    86     ElementVector m_Children; 
     119    void updated(int new_nb_elements); 
     120    void setVerboseLevel(int i); 
     121private: 
     122    Element *createHandler(Element *, Control::Element& e); 
     123    void updateTree(); 
     124    Element * findElementForControl(Control::Element *e); 
     125    void removeElement(Element *e); 
     126 
     127    Control::Container &        m_Slave; 
     128    ElementVector               m_Children; 
     129    Control::SignalFunctor *    m_updateFunctor; 
    87130}; 
    88131 
     
    93136public: 
    94137    Continuous( DBus::Connection& connection, 
    95                   std::string p, 
     138                  std::string p, Element *, 
    96139                  Control::Continuous &slave ); 
    97140     
     
    114157public: 
    115158    Discrete( DBus::Connection& connection, 
    116               std::string p, 
     159              std::string p, Element *, 
    117160              Control::Discrete &slave ); 
    118161     
     
    133176public: 
    134177    Text( DBus::Connection& connection, 
    135           std::string p, 
     178          std::string p, Element *, 
    136179          Control::Text &slave ); 
    137180 
     
    149192public: 
    150193    Register( DBus::Connection& connection, 
    151               std::string p, 
     194              std::string p, Element *, 
    152195              Control::Register &slave ); 
    153196     
     
    165208public: 
    166209    Enum( DBus::Connection& connection, 
    167           std::string p, 
     210          std::string p, Element *, 
    168211          Control::Enum &slave ); 
    169212     
     
    183226public: 
    184227    AttributeEnum( DBus::Connection& connection, 
    185                    std::string p, 
     228                   std::string p, Element *, 
    186229                   Control::AttributeEnum &slave ); 
    187230     
     
    206249public: 
    207250    ConfigRomX( DBus::Connection& connection, 
    208                   std::string p, 
     251                  std::string p, Element *, 
    209252                  ConfigRom &slave ); 
    210253 
     
    226269public: 
    227270    MatrixMixer(  DBus::Connection& connection, 
    228                   std::string p, 
     271                  std::string p, Element *, 
    229272                  Control::MatrixMixer &slave ); 
    230273 
  • trunk/libffado/support/dbus/ffado-dbus-server.cpp

    r1158 r1163  
    204204 
    205205void 
    206 busresetHandler() 
    207 
    208     // this is a race condition: the control tree becomes invalid since we 
    209     // are redetecting the devices, but the dispatcher still allows access. 
    210     // at this point. This has to be split up in two. 
    211     debugOutput( DEBUG_LEVEL_NORMAL, "notified of bus reset...\n" ); 
     206preUpdateHandler() 
     207
     208    debugOutput( DEBUG_LEVEL_NORMAL, "got pre-update notification...\n" ); 
     209    // stop receiving dbus events since the control structure is going to 
     210    // be changed 
    212211    dispatcher.leave(); 
    213  
    214     // delete old container 
    215     delete container; 
    216     container = NULL; 
    217  
    218     // build new one 
    219     if(m_deviceManager) { 
    220         container = new DBusControl::Container(*global_conn, "/org/ffado/Control/DeviceManager", *m_deviceManager); 
    221     } else { 
    222         debugError("no device manager, bailing out\n"); 
    223         run=0; 
    224     } 
     212
     213 
     214void 
     215postUpdateHandler() 
     216
     217    debugOutput( DEBUG_LEVEL_NORMAL, "got post-update notification...\n" ); 
     218    // the signal handlers registered by the elements should have taken 
     219    // care of updating the control tree 
     220 
     221    // signal that we can start receiving dbus events again 
    225222    sem_post(&run_sem); 
    226223} 
     
    272269        } 
    273270 
    274         // add busreset handler 
    275         Util::Functor* tmp_busreset_functor = new Util::CallbackFunctor0< void (*)() > 
    276                     ( &busresetHandler, false ); 
    277         if ( !tmp_busreset_functor ) { 
    278             debugFatal( "Could not create busreset handler\n" ); 
     271        // add pre-update handler 
     272        Util::Functor* preupdate_functor = new Util::CallbackFunctor0< void (*)() > 
     273                    ( &preUpdateHandler, false ); 
     274        if ( !preupdate_functor ) { 
     275            debugFatal( "Could not create pre-update handler\n" ); 
    279276            return false; 
    280277        } 
    281         if(!m_deviceManager->registerBusresetNotification(tmp_busreset_functor)) { 
    282             debugError("could not register busreset notifier"); 
     278        if(!m_deviceManager->registerPreUpdateNotification(preupdate_functor)) { 
     279            debugError("could not register pre-update notifier"); 
     280        } 
     281        // add post-update handler 
     282        Util::Functor* postupdate_functor = new Util::CallbackFunctor0< void (*)() > 
     283                    ( &postUpdateHandler, false ); 
     284        if ( !postupdate_functor ) { 
     285            debugFatal( "Could not create post-update handler\n" ); 
     286            return false; 
     287        } 
     288        if(!m_deviceManager->registerPostUpdateNotification(postupdate_functor)) { 
     289            debugError("could not register post-update notifier"); 
    283290        } 
    284291 
     
    293300        conn.request_name("org.ffado.Control"); 
    294301 
    295         container = new DBusControl::Container(conn, "/org/ffado/Control/DeviceManager", *m_deviceManager); 
     302        container = new DBusControl::Container(conn, "/org/ffado/Control/DeviceManager",  
     303                                               NULL, *m_deviceManager); 
    296304         
    297305        printMessage("DBUS test service running\n"); 
     
    301309            debugOutput( DEBUG_LEVEL_NORMAL, "dispatching...\n"); 
    302310            dispatcher.enter(); 
     311            debugOutput( DEBUG_LEVEL_NORMAL, " dispatcher exited...\n"); 
    303312            sem_wait(&run_sem); 
     313            debugOutput( DEBUG_LEVEL_NORMAL, " activity handled...\n"); 
    304314        } 
    305315         
    306         if(!m_deviceManager->unregisterBusresetNotification(tmp_busreset_functor)) { 
    307             debugError("could not unregister busreset notifier"); 
    308         } 
    309         delete tmp_busreset_functor; 
     316        if(!m_deviceManager->unregisterPreUpdateNotification(preupdate_functor)) { 
     317            debugError("could not unregister pre update notifier"); 
     318        } 
     319        delete preupdate_functor; 
     320        if(!m_deviceManager->unregisterPostUpdateNotification(postupdate_functor)) { 
     321            debugError("could not unregister post update notifier"); 
     322        } 
     323        delete postupdate_functor; 
    310324        delete container; 
    311325 
  • trunk/libffado/support/dbus/test-dbus-server.cpp

    r1158 r1163  
    161161    // the container is deleted before the children become invalid 
    162162    DBusControl::Container *container 
    163         = new DBusControl::Container(conn, "/org/ffado/Control/Test/Container", cont); 
     163        = new DBusControl::Container(conn, "/org/ffado/Control/Test/Container", NULL, cont); 
    164164 
    165165    dispatcher.enter(); 
  • trunk/libffado/support/mixer/ffadomixer.in

    r1094 r1163  
    3333import time 
    3434import dbus 
     35 
    3536from qt import * 
    3637 
     
    170171        self.dev = self.bus.get_object(self.servername, self.basepath) 
    171172        self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.Container') 
     173        # signal reception does not work yet since we need a mainloop for that 
     174        # and qt3 doesn't provide one for python/dbus 
     175        #try: 
     176            #self.dev.connect_to_signal("Updated", self.updateSignal, \ 
     177                                       #dbus_interface="org.ffado.Control.Element.Container", arg0=self) 
     178        #except dbus.DBusException: 
     179            #traceback.print_exc() 
     180 
     181    #def updateSignal(self): 
     182        #print ("Received update signal") 
    172183 
    173184    def getNbDevices(self): 
    174185        return self.iface.getNbElements() 
    175186    def getDeviceName(self, idx): 
    176         return self.iface.getElementName(idx)   
     187        return self.iface.getElementName(idx) 
     188 
    177189 
    178190class ConfigRomInterface: