VirtualBox

Changeset 50945 in vbox


Ignore:
Timestamp:
Apr 1, 2014 3:16:22 PM (11 years ago)
Author:
vboxsync
Message:

ConsoleImpl: fix a race at SafeVMPtr.

File:
1 edited

Legend:

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

    r50736 r50945  
    338338        ~AutoVMCallerBase()
    339339        {
    340             if (SUCCEEDED(mRC))
    341                 mThat->releaseVMCaller();
     340            doRelease();
    342341        }
    343342        /** Decreases the number of callers before the instance is destroyed. */
    344343        void releaseCaller()
    345344        {
    346             AssertReturnVoid(SUCCEEDED(mRC));
    347             mThat->releaseVMCaller();
    348             mRC = E_FAIL;
     345            Assert(SUCCEEDED(mRC));
     346            doRelease();
    349347        }
    350348        /** Restores the number of callers after by #release(). #rc() must be
     
    361359    protected:
    362360        Console *mThat;
    363         HRESULT mRC;
     361        void doRelease()
     362        {
     363            if (SUCCEEDED(mRC))
     364            {
     365                mThat->releaseVMCaller();
     366                mRC = E_FAIL;
     367            }
     368        }
    364369    private:
     370        HRESULT mRC; /* Whether the caller was added. */
    365371        DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoVMCallerBase)
    366372    };
     
    422428        typedef AutoVMCallerBase<taQuiet, true> Base;
    423429    public:
    424         SafeVMPtrBase(Console *aThat) : Base(aThat), mpUVM(NULL)
    425         {
    426             if (SUCCEEDED(Base::mRC))
    427                 Base::mRC = aThat->safeVMPtrRetainer(&mpUVM, taQuiet);
     430        SafeVMPtrBase(Console *aThat) : Base(aThat), mRC(S_OK), mpUVM(NULL)
     431        {
     432            if (Base::isOk())
     433                mRC = aThat->safeVMPtrRetainer(&mpUVM, taQuiet);
    428434        }
    429435        ~SafeVMPtrBase()
    430436        {
    431             if (SUCCEEDED(Base::mRC))
    432                 release();
     437            doRelease();
    433438        }
    434439        /** Direct PUVM access. */
     
    437442        void release()
    438443        {
    439             AssertReturnVoid(SUCCEEDED(Base::mRC));
    440             Base::mThat->safeVMPtrReleaser(&mpUVM);
    441             Base::releaseCaller();
     444            Assert(SUCCEEDED(mRC));
     445            doRelease();
    442446        }
    443447
     448        /** The combined result of Console::addVMCaller() and Console::safeVMPtrRetainer */
     449        HRESULT rc() const { return SUCCEEDED(mRC)? Base::rc(): mRC; }
     450        /** Shortcut to SUCCEEDED(rc()) */
     451        bool isOk() const { return SUCCEEDED(mRC) && Base::isOk(); }
     452
    444453    private:
     454        void doRelease()
     455        {
     456            if (SUCCEEDED(mRC))
     457            {
     458                Base::mThat->safeVMPtrReleaser(&mpUVM);
     459                mRC = E_FAIL;
     460            }
     461            Base::doRelease();
     462        }
     463        HRESULT mRC; /* Whether the VM ptr was retained. */
    445464        PUVM    mpUVM;
    446465        DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(SafeVMPtrBase)
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