VirtualBox

Changeset 2804 in vbox for trunk/src/VBox/Main/include


Ignore:
Timestamp:
May 23, 2007 1:44:21 PM (18 years ago)
Author:
vboxsync
Message:

Main: Added Machine::AutoStateDependency smart class that helps to ensure the machine state won't unexpectedly change, in a lock-free manner.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/MachineImpl.h

    r2567 r2804  
    5959 *  @param machine  the machine object (must cast to Machine *)
    6060 */
     61/// @todo replace with AutoStateDependency
    6162#define CHECK_MACHINE_MUTABILITY(machine) \
    6263    do { \
     
    6465            return setError (E_ACCESSDENIED, tr ("The machine is not mutable")); \
    6566    } while (0)
    66 /** like CHECK_MACHINE_MUTABILITY but a saved state is ok, too */
     67
     68/** Like CHECK_MACHINE_MUTABILITY but a saved state is OK, too. */
     69/// @todo replace with AutoStateDependency
    6770#define CHECK_MACHINE_MUTABILITY_IGNORING_SAVED(machine) \
    6871    do { \
    6972        if (!machine->isMutableIgnoringSavedState()) \
    70             return setError (E_ACCESSDENIED, tr ("The machine is not mutable or in saved state")); \
     73            return setError (E_ACCESSDENIED, \
     74                             tr ("The machine is not mutable or in saved state")); \
    7175    } while (0)
    7276
     
    167171        LONG64 mLastStateChange;
    168172
     173        uint32_t mMachineStateDeps;
     174        RTSEMEVENT mZeroMachineStateDepsSem;
     175        BOOL mWaitingStateDeps;
     176
    169177        BOOL mCurrentStateModified;
    170178
     
    277285         */
    278286        bool mHDAttachmentsChanged;
     287    };
     288
     289    enum StateDependency
     290    {
     291        AnyStateDep = 0, MutableStateDep, MutableOrSavedStateDep
     292    };
     293
     294    /**
     295     *  Helper class that safely manages the machine state dependency by
     296     *  calling Machine::addStateDependency() on construction and
     297     *  Machine::releaseStateDependency() on destruction. Intended for Machine
     298     *  children. The usage pattern is:
     299     *
     300     *  @code
     301     *      Machine::AutoStateDependency <MutableStateDep> adep (mParent);
     302     *      CheckComRCReturnRC (stateDep.rc());
     303     *      ...
     304     *      // code that depends on the particular machine state
     305     *      ...
     306     *  @endcode
     307     *
     308     *  @param taDepType    Dependecy type to manage.
     309     */
     310    template <StateDependency taDepType = AnyStateDep>
     311    class AutoStateDependency
     312    {
     313    public:
     314
     315        AutoStateDependency (Machine *aThat)
     316            : mThat (aThat), mRC (S_OK)
     317            , mMachineState (MachineState_InvalidMachineState)
     318            , mRegistered (FALSE)
     319        {
     320            Assert (aThat);
     321            mRC = aThat->addStateDependency (taDepType, &mMachineState,
     322                                             &mRegistered);
     323        }
     324        ~AutoStateDependency()
     325        {
     326            if (SUCCEEDED (mRC))
     327                mThat->releaseStateDependency();
     328        }
     329
     330        /** Decreases the number of dependencies before the instance is
     331         *  destroyed. Note that will reset #rc() to E_FAIL. */
     332        void release()
     333        {
     334            AssertReturnVoid (SUCCEEDED (mRC));
     335            mThat->releaseStateDependency();
     336            mRC = E_FAIL;
     337        }
     338
     339        /** Restores the number of callers after by #release(). #rc() will be
     340         *  reset to the result of calling addStateDependency() and must be
     341         *  rechecked to ensure the operation succeeded. */
     342        void add()
     343        {
     344            AssertReturnVoid (!SUCCEEDED (mRC));
     345            mRC = mThat->addStateDependency (taDepType, &mMachineState,
     346                                             &mRegistered);
     347        }
     348
     349        /** Returns the result of Machine::addStateDependency(). */
     350        HRESULT rc() const { return mRC; }
     351
     352        /** Shortcut to SUCCEEDED (rc()). */
     353        bool isOk() const { return SUCCEEDED (mRC); }
     354
     355        /** Returns the machine state value as returned by
     356         *  Machine::addStateDependency(). */
     357        MachineState_T machineState() const { return mMachineState; }
     358
     359        /** Returns the machine state value as returned by
     360         *  Machine::addStateDependency(). */
     361        BOOL machineRegistered() const { return mRegistered; }
     362
     363    protected:
     364
     365        Machine *mThat;
     366        HRESULT mRC;
     367        MachineState_T mMachineState;
     368        BOOL mRegistered;
     369
     370    private:
     371
     372        DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (AutoStateDependency)
     373        DECLARE_CLS_NEW_DELETE_NOOP (AutoStateDependency)
    279374    };
    280375
     
    375470    //  Note: these classes should enter Machine lock to keep the returned
    376471    //  information valid!
     472    /// @todo replace with AutoStateDependency
    377473    bool isMutable()
    378474    {
     
    387483    //  Note: these classes should enter Machine lock to keep the returned
    388484    //  information valid!
     485    /// @todo replace with AutoStateDependency
    389486    bool isMutableIgnoringSavedState()
    390487    {
     
    446543    }
    447544
     545    HRESULT addStateDependency (StateDependency aDepType = AnyStateDep,
     546                                MachineState_T *aState = NULL,
     547                                BOOL *aRegistered = NULL);
     548    void releaseStateDependency();
     549
    448550    // for VirtualBoxSupportErrorInfoImpl
    449551    static const wchar_t *getComponentName() { return L"Machine"; }
     
    458560
    459561    void uninitDataAndChildObjects();
     562
     563    void checkStateDependencies (AutoLock &aLock);
    460564
    461565    virtual HRESULT setMachineState (MachineState_T aMachineState);
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