VirtualBox

Changeset 33708 in vbox


Ignore:
Timestamp:
Nov 2, 2010 6:46:46 PM (14 years ago)
Author:
vboxsync
Message:

Main: Eliminate the last bits of VirtualBoxBaseWithChildrenNEXT. It won't be missed.

Location:
trunk/src/VBox/Main
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r33621 r33708  
    507507
    508508    LogFlowThisFunc(("initFailed()=%d\n", autoUninitSpan.initFailed()));
    509 
    510     /*
    511      * Uninit all children that use addDependentChild()/removeDependentChild()
    512      * in their init()/uninit() methods.
    513      */
    514     uninitDependentChildren();
    515509
    516510    /* power down the VM if necessary */
  • trunk/src/VBox/Main/DisplayImpl.cpp

    r33685 r33708  
    27892789
    27902790    /// @todo (dmik) can we AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); here?
    2791     //  do it when we switch this class to VirtualBoxBase_NEXT.
    27922791    //  This will require general code review and may add some details.
    27932792    //  In particular, we may want to check whether EMT is really waiting for
  • trunk/src/VBox/Main/MachineImpl.cpp

    r33596 r33708  
    65796579                           || autoCaller.state() == Limited);
    65806580
    6581     /* uninit all children using addDependentChild()/removeDependentChild()
    6582      * in their init()/uninit() methods */
    6583     uninitDependentChildren();
    6584 
    65856581    /* tell all our other child objects we've been uninitialized */
    65866582
  • trunk/src/VBox/Main/MediumImpl.cpp

    r33622 r33708  
    13241324    if (m->state == MediumState_Deleting)
    13251325    {
    1326         /* we are being reinitialized after we've been deleted by merge.
    1327          * Reparenting has already been done so don't touch it here (we are
    1328          * now orphans and removeDependentChild() will assert) */
     1326        /* This medium has been already deleted (directly or as part of a
     1327         * merge).  Reparenting has already been done. */
    13291328        Assert(m->pParent.isNull());
    13301329    }
  • trunk/src/VBox/Main/MouseImpl.cpp

    r33321 r33708  
    577577
    578578    rc = reportAbsEvent(mouseXAbs, mouseYAbs, dz, dw, fButtons,
    579                         mouseCaps & VMMDEV_MOUSE_GUEST_USES_EVENT);
     579                        !!(mouseCaps & VMMDEV_MOUSE_GUEST_USES_EVENT));
    580580
    581581#ifndef VBOXBFE_WITHOUT_COM
  • trunk/src/VBox/Main/StorageControllerImpl.cpp

    r32531 r33708  
    150150
    151151    /* m->pPeer is left null */
    152 
    153     /* register with parent early, since uninit() will unconditionally
    154      * unregister on failure */
    155     m->pParent->addDependentChild(this);
    156152
    157153    m->bd.allocate();
     
    227223    m = new Data(aParent);
    228224
    229     /* register with parent early, since uninit() will unconditionally
    230      * unregister on failure */
    231     m->pParent->addDependentChild(this);
    232 
    233225    /* sanity */
    234226    AutoCaller thatCaller(aThat);
     
    274266    /* m->pPeer is left null */
    275267
    276     m->pParent->addDependentChild(this);
    277 
    278268    AutoCaller thatCaller(aThat);
    279269    AssertComRCReturnRC(thatCaller.rc());
     
    303293
    304294    m->bd.free();
    305 
    306     m->pParent->removeDependentChild(this);
    307295
    308296    unconst(m->pPeer) = NULL;
  • trunk/src/VBox/Main/USBControllerImpl.cpp

    r31539 r33708  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2010 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    507507    ComObjPtr<USBDeviceFilter> filter = static_cast<USBDeviceFilter*>(aFilter);
    508508    // @todo r=dj make sure the input object is actually from us
    509 //     ComObjPtr<USBDeviceFilter> filter = getDependentChild(aFilter);
    510509//     if (!filter)
    511510//         return setError (E_INVALIDARG,
  • trunk/src/VBox/Main/VirtualBoxBase.cpp

    r33621 r33708  
    696696            /* otherwise, wait until another thread finishes uninitialization.
    697697             * This is necessary to make sure that when this method returns, the
    698              * object is NotReady and therefore can be deleted (for example).
    699              * In particular, this is used by
    700              * VirtualBoxBaseWithTypedChildrenNEXT::uninitDependentChildren(). */
     698             * object is NotReady and therefore can be deleted (for example). */
    701699
    702700            /* lazy semaphore creation */
     
    763761////////////////////////////////////////////////////////////////////////////////
    764762//
    765 // VirtualBoxBaseWithChildrenNEXT methods
    766 //
    767 ////////////////////////////////////////////////////////////////////////////////
    768 
    769 /**
    770  * Uninitializes all dependent children registered on this object with
    771  * #addDependentChild().
    772  *
    773  * Must be called from within the AutoUninitSpan (i.e.
    774  * typically from this object's uninit() method) to uninitialize children
    775  * before this object goes out of service and becomes unusable.
    776  *
    777  * Note that this method will call uninit() methods of child objects. If
    778  * these methods need to call the parent object during uninitialization,
    779  * #uninitDependentChildren() must be called before the relevant part of the
    780  * parent is uninitialized: usually at the beginning of the parent
    781  * uninitialization sequence.
    782  *
    783  * Keep in mind that the uninitialized child objects may be no longer available
    784  * (i.e. may be deleted) after this method returns.
    785  *
    786  * @note Locks #childrenLock() for writing.
    787  *
    788  * @note May lock something else through the called children.
    789  */
    790 void VirtualBoxBaseWithChildrenNEXT::uninitDependentChildren()
    791 {
    792     AutoCaller autoCaller(this);
    793 
    794     /* sanity */
    795     AssertReturnVoid (autoCaller.state() == InUninit ||
    796                       autoCaller.state() == InInit);
    797 
    798     AutoWriteLock chLock(childrenLock() COMMA_LOCKVAL_SRC_POS);
    799 
    800     size_t count = mDependentChildren.size();
    801 
    802     while (count != 0)
    803     {
    804         /* strongly reference the weak child from the map to make sure it won't
    805          * be deleted while we've released the lock */
    806         DependentChildren::iterator it = mDependentChildren.begin();
    807         ComPtr<IUnknown> unk = it->first;
    808         Assert(!unk.isNull());
    809 
    810         VirtualBoxBase *child = it->second;
    811 
    812         /* release the lock to let children stuck in removeDependentChild() go
    813          * on (otherwise we'll deadlock in uninit() */
    814         chLock.leave();
    815 
    816         /* Note that if child->uninit() happens to be called on another
    817          * thread right before us and is not yet finished, the second
    818          * uninit() call will wait until the first one has done so
    819          * (thanks to AutoUninitSpan). */
    820         Assert(child);
    821         if (child)
    822             child->uninit();
    823 
    824         chLock.enter();
    825 
    826         /* uninit() is guaranteed to be done here so the child must be already
    827          * deleted from the list by removeDependentChild() called from there.
    828          * Do some checks to avoid endless loops when the user is forgetful */
    829         -- count;
    830         Assert(count == mDependentChildren.size());
    831         if (count != mDependentChildren.size())
    832             mDependentChildren.erase (it);
    833 
    834         Assert(count == mDependentChildren.size());
    835     }
    836 }
    837 
    838 /**
    839  * Returns a pointer to the dependent child (registered using
    840  * #addDependentChild()) corresponding to the given interface pointer or NULL if
    841  * the given pointer is unrelated.
    842  *
    843  * The relation is checked by using the given interface pointer as a key in the
    844  * map of dependent children.
    845  *
    846  * Note that ComPtr<IUnknown> is used as an argument instead of IUnknown * in
    847  * order to guarantee IUnknown identity and disambiguation by doing
    848  * QueryInterface (IUnknown) rather than a regular C cast.
    849  *
    850  * @param aUnk  Pointer to map to the dependent child object.
    851  * @return      Pointer to the dependent VirtualBoxBase child object.
    852  *
    853  * @note Locks #childrenLock() for reading.
    854  */
    855 VirtualBoxBase* VirtualBoxBaseWithChildrenNEXT::getDependentChild(const ComPtr<IUnknown> &aUnk)
    856 {
    857     AssertReturn(!aUnk.isNull(), NULL);
    858 
    859     AutoCaller autoCaller(this);
    860 
    861     /* return NULL if uninitDependentChildren() is in action */
    862     if (autoCaller.state() == InUninit)
    863         return NULL;
    864 
    865     AutoReadLock alock(childrenLock() COMMA_LOCKVAL_SRC_POS);
    866 
    867     DependentChildren::const_iterator it = mDependentChildren.find (aUnk);
    868     if (it == mDependentChildren.end())
    869         return NULL;
    870 
    871     return (*it).second;
    872 }
    873 
    874 /** Helper for addDependentChild(). */
    875 void VirtualBoxBaseWithChildrenNEXT::doAddDependentChild(IUnknown *aUnk,
    876                                                          VirtualBoxBase *aChild)
    877 {
    878     AssertReturnVoid (aUnk != NULL);
    879     AssertReturnVoid (aChild != NULL);
    880 
    881     AutoCaller autoCaller(this);
    882 
    883     /* sanity */
    884     AssertReturnVoid (autoCaller.state() == InInit ||
    885                       autoCaller.state() == Ready ||
    886                       autoCaller.state() == Limited);
    887 
    888     AutoWriteLock alock(childrenLock() COMMA_LOCKVAL_SRC_POS);
    889 
    890     std::pair <DependentChildren::iterator, bool> result =
    891         mDependentChildren.insert (DependentChildren::value_type (aUnk, aChild));
    892     AssertMsg (result.second, ("Failed to insert child %p to the map\n", aUnk));
    893 }
    894 
    895 /** Helper for removeDependentChild(). */
    896 void VirtualBoxBaseWithChildrenNEXT::doRemoveDependentChild (IUnknown *aUnk)
    897 {
    898     AssertReturnVoid (aUnk);
    899 
    900     AutoCaller autoCaller(this);
    901 
    902     /* sanity */
    903     AssertReturnVoid (autoCaller.state() == InUninit ||
    904                       autoCaller.state() == InInit ||
    905                       autoCaller.state() == Ready ||
    906                       autoCaller.state() == Limited);
    907 
    908     AutoWriteLock alock(childrenLock() COMMA_LOCKVAL_SRC_POS);
    909 
    910     DependentChildren::size_type result = mDependentChildren.erase (aUnk);
    911     AssertMsg (result == 1, ("Failed to remove child %p from the map\n", aUnk));
    912     NOREF (result);
    913 }
    914 
    915 ////////////////////////////////////////////////////////////////////////////////
    916 //
    917763// MultiResult methods
    918764//
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r33540 r33708  
    7979/** IConsole implementation class */
    8080class ATL_NO_VTABLE Console :
    81     public VirtualBoxBaseWithChildrenNEXT,
     81    public VirtualBoxBase,
    8282    VBOX_SCRIPTABLE_IMPL(IConsole)
    8383#ifdef RT_OS_WINDOWS
  • trunk/src/VBox/Main/include/MachineImpl.h

    r33592 r33708  
    8181
    8282class ATL_NO_VTABLE Machine :
    83     public VirtualBoxBaseWithChildrenNEXT,
     83    public VirtualBoxBase,
    8484    VBOX_SCRIPTABLE_IMPL(IMachine)
    8585{
  • trunk/src/VBox/Main/include/SharedFolderImpl.h

    r31002 r33708  
    2525
    2626class ATL_NO_VTABLE SharedFolder :
    27     public VirtualBoxBaseWithChildrenNEXT,
     27    public VirtualBoxBase,
    2828    VBOX_SCRIPTABLE_IMPL(ISharedFolder)
    2929{
  • trunk/src/VBox/Main/include/VirtualBoxBase.h

    r33540 r33708  
    630630     * last reference to the object is released, before calling the destructor.
    631631     *
    632      * This method is also automatically called by the uninit() method of this
    633      * object's parent if this object is a dependent child of a class derived
    634      * from VirtualBoxBaseWithChildren (see
    635      * VirtualBoxBaseWithChildren::addDependentChild).
    636      *
    637632     * @note Never call this method the AutoCaller scope or after the
    638633     *       #addCaller() call not paired by #releaseCaller() because it is a
     
    748743////////////////////////////////////////////////////////////////////////////////
    749744
    750 /**
    751  * Base class to track VirtualBoxBaseNEXT chlidren of the component.
    752  *
    753  * This class is a preferable VirtualBoxBase replacement for components that
    754  * operate with collections of child components. It gives two useful
    755  * possibilities:
    756  *
    757  * <ol><li>
    758  *      Given an IUnknown instance, it's possible to quickly determine
    759  *      whether this instance represents a child object that belongs to the
    760  *      given component, and if so, get a valid VirtualBoxBase pointer to the
    761  *      child object. The returned pointer can be then safely casted to the
    762  *      actual class of the child object (to get access to its "internal"
    763  *      non-interface methods) provided that no other child components implement
    764  *      the same original COM interface IUnknown is queried from.
    765  * </li><li>
    766  *      When the parent object uninitializes itself, it can easily uninitialize
    767  *      all its VirtualBoxBase derived children (using their
    768  *      VirtualBoxBase::uninit() implementations). This is done simply by
    769  *      calling the #uninitDependentChildren() method.
    770  * </li></ol>
    771  *
    772  * In order to let the above work, the following must be done:
    773  * <ol><li>
    774  *      When a child object is initialized, it calls #addDependentChild() of
    775  *      its parent to register itself within the list of dependent children.
    776  * </li><li>
    777  *      When the child object it is uninitialized, it calls
    778  *      #removeDependentChild() to unregister itself.
    779  * </li></ol>
    780  *
    781  * Note that if the parent object does not call #uninitDependentChildren() when
    782  * it gets uninitialized, it must call uninit() methods of individual children
    783  * manually to disconnect them; a failure to do so will cause crashes in these
    784  * methods when children get destroyed. The same applies to children not calling
    785  * #removeDependentChild() when getting destroyed.
    786  *
    787  * Note that children added by #addDependentChild() are <b>weakly</b> referenced
    788  * (i.e. AddRef() is not called), so when a child object is deleted externally
    789  * (because it's reference count goes to zero), it will automatically remove
    790  * itself from the map of dependent children provided that it follows the rules
    791  * described here.
    792  *
    793  * Access to the child list is serialized using the #childrenLock() lock handle
    794  * (which defaults to the general object lock handle (see
    795  * VirtualBoxBase::lockHandle()). This lock is used by all add/remove methods of
    796  * this class so be aware of the need to preserve the {parent, child} lock order
    797  * when calling these methods.
    798  *
    799  * Read individual method descriptions to get further information.
    800  *
    801  * @todo This is a VirtualBoxBaseWithChildren equivalent that uses the
    802  *       VirtualBoxBaseNEXT implementation. Will completely supersede
    803  *       VirtualBoxBaseWithChildren after the old VirtualBoxBase implementation
    804  *       has gone.
    805  */
    806 class VirtualBoxBaseWithChildrenNEXT : public VirtualBoxBase
    807 {
    808 public:
    809 
    810     VirtualBoxBaseWithChildrenNEXT()
    811     {}
    812 
    813     virtual ~VirtualBoxBaseWithChildrenNEXT()
    814     {}
    815 
    816     /**
    817      * Lock handle to use when adding/removing child objects from the list of
    818      * children. It is guaranteed that no any other lock is requested in methods
    819      * of this class while holding this lock.
    820      *
    821      * @warning By default, this simply returns the general object's lock handle
    822      *          (see VirtualBoxBase::lockHandle()) which is sufficient for most
    823      *          cases.
    824      */
    825     virtual RWLockHandle *childrenLock() { return lockHandle(); }
    826 
    827     /**
    828      * Adds the given child to the list of dependent children.
    829      *
    830      * Usually gets called from the child's init() method.
    831      *
    832      * @note @a aChild (unless it is in InInit state) must be protected by
    833      *       VirtualBoxBase::AutoCaller to make sure it is not uninitialized on
    834      *       another thread during this method's call.
    835      *
    836      * @note When #childrenLock() is not overloaded (returns the general object
    837      *       lock) and this method is called from under the child's read or
    838      *       write lock, make sure the {parent, child} locking order is
    839      *       preserved by locking the callee (this object) for writing before
    840      *       the child's lock.
    841      *
    842      * @param aChild    Child object to add (must inherit VirtualBoxBase AND
    843      *                  implement some interface).
    844      *
    845      * @note Locks #childrenLock() for writing.
    846      */
    847     template<class C>
    848     void addDependentChild(C *aChild)
    849     {
    850         AssertReturnVoid(aChild != NULL);
    851         doAddDependentChild(ComPtr<IUnknown>(aChild), aChild);
    852     }
    853 
    854     /**
    855      * Equivalent to template <class C> void addDependentChild (C *aChild)
    856      * but takes a ComObjPtr<C> argument.
    857      */
    858     template<class C>
    859     void addDependentChild(const ComObjPtr<C> &aChild)
    860     {
    861         AssertReturnVoid(!aChild.isNull());
    862         doAddDependentChild(ComPtr<IUnknown>(static_cast<C *>(aChild)), aChild);
    863     }
    864 
    865     /**
    866      * Removes the given child from the list of dependent children.
    867      *
    868      * Usually gets called from the child's uninit() method.
    869      *
    870      * Keep in mind that the called (parent) object may be no longer available
    871      * (i.e. may be deleted deleted) after this method returns, so you must not
    872      * call any other parent's methods after that!
    873      *
    874      * @note Locks #childrenLock() for writing.
    875      *
    876      * @note @a aChild (unless it is in InUninit state) must be protected by
    877      *       VirtualBoxBase::AutoCaller to make sure it is not uninitialized on
    878      *       another thread during this method's call.
    879      *
    880      * @note When #childrenLock() is not overloaded (returns the general object
    881      *       lock) and this method is called from under the child's read or
    882      *       write lock, make sure the {parent, child} locking order is
    883      *       preserved by locking the callee (this object) for writing before
    884      *       the child's lock. This is irrelevant when the method is called from
    885      *       under this object's VirtualBoxBaseProto::AutoUninitSpan (i.e. in
    886      *       InUninit state) since in this case no locking is done.
    887      *
    888      * @param aChild    Child object to remove.
    889      *
    890      * @note Locks #childrenLock() for writing.
    891      */
    892     template<class C>
    893     void removeDependentChild(C *aChild)
    894     {
    895         AssertReturnVoid(aChild != NULL);
    896         doRemoveDependentChild(ComPtr<IUnknown>(aChild));
    897     }
    898 
    899     /**
    900      * Equivalent to template <class C> void removeDependentChild (C *aChild)
    901      * but takes a ComObjPtr<C> argument.
    902      */
    903     template<class C>
    904     void removeDependentChild(const ComObjPtr<C> &aChild)
    905     {
    906         AssertReturnVoid(!aChild.isNull());
    907         doRemoveDependentChild(ComPtr<IUnknown>(static_cast<C *>(aChild)));
    908     }
    909 
    910 protected:
    911 
    912     void uninitDependentChildren();
    913 
    914     VirtualBoxBase *getDependentChild(const ComPtr<IUnknown> &aUnk);
    915 
    916 private:
    917     void doAddDependentChild(IUnknown *aUnk, VirtualBoxBase *aChild);
    918     void doRemoveDependentChild(IUnknown *aUnk);
    919 
    920     typedef std::map<IUnknown*, VirtualBoxBase*> DependentChildren;
    921     DependentChildren mDependentChildren;
    922 };
    923 
    924 ////////////////////////////////////////////////////////////////////////////////
    925 
    926745////////////////////////////////////////////////////////////////////////////////
    927746
     
    1022841};
    1023842
    1024 /// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely
    1025843/**
    1026844 *  Simple template that enhances Shareable<> and supports data
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette