84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/* $Id$ */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/** @file
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * VirtualBox object state implementation
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/*
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Copyright (C) 2006-2014 Oracle Corporation
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * available from http://www.virtualbox.org. This file is free software;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * you can redistribute it and/or modify it under the terms of the GNU
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * General Public License (GPL) as published by the Free Software
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync#include <iprt/semaphore.h>
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync#include "VirtualBoxBase.h"
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync#include "AutoCaller.h"
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync#include "Logging.h"
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync////////////////////////////////////////////////////////////////////////////////
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync//
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync// ObjectState methods
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync//
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync////////////////////////////////////////////////////////////////////////////////
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncObjectState::ObjectState() : mStateLock(LOCKCLASS_OBJECTSTATE)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AssertFailed();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncObjectState::ObjectState(VirtualBoxBase *aObj) :
1c754011e968403645da177801a9affaeec0e4fdvboxsync mObj(aObj), mStateLock(LOCKCLASS_OBJECTSTATE)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mObj);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mState = NotReady;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mStateChangeThread = NIL_RTTHREAD;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mCallers = 0;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mZeroCallersSem = NIL_RTSEMEVENT;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mInitUninitSem = NIL_RTSEMEVENTMULTI;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mInitUninitWaiters = 0;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncObjectState::~ObjectState()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mInitUninitWaiters == 0);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mInitUninitSem == NIL_RTSEMEVENTMULTI);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mZeroCallersSem != NIL_RTSEMEVENT)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventDestroy(mZeroCallersSem);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mCallers = 0;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mStateChangeThread = NIL_RTTHREAD;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mState = NotReady;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mObj = NULL;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncObjectState::State ObjectState::getState()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AutoReadLock stateLock(mStateLock COMMA_LOCKVAL_SRC_POS);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return mState;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/**
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Increments the number of calls to this object by one.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * After this method succeeds, it is guaranteed that the object will remain
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * in the Ready (or in the Limited) state at least until #releaseCaller() is
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * called.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * This method is intended to mark the beginning of sections of code within
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * methods of COM objects that depend on the readiness (Ready) state. The
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Ready state is a primary "ready to serve" state. Usually all code that
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * works with component's data depends on it. On practice, this means that
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * almost every public method, setter or getter of the object should add
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * itself as an object's caller at the very beginning, to protect from an
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * unexpected uninitialization that may happen on a different thread.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Besides the Ready state denoting that the object is fully functional,
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * there is a special Limited state. The Limited state means that the object
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * is still functional, but its functionality is limited to some degree, so
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * not all operations are possible. The @a aLimited argument to this method
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * determines whether the caller represents this limited functionality or
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * not.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * This method succeeds (and increments the number of callers) only if the
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * current object's state is Ready. Otherwise, it will return E_ACCESSDENIED
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * to indicate that the object is not operational. There are two exceptions
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * from this rule:
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * <ol>
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * <li>If the @a aLimited argument is |true|, then this method will also
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * succeed if the object's state is Limited (or Ready, of course).
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * </li>
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * <li>If this method is called from the same thread that placed
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * the object to InInit or InUninit state (i.e. either from within the
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * AutoInitSpan or AutoUninitSpan scope), it will succeed as well (but
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * will not increase the number of callers).
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * </li>
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * </ol>
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Normally, calling addCaller() never blocks. However, if this method is
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * called by a thread created from within the AutoInitSpan scope and this
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * scope is still active (i.e. the object state is InInit), it will block
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * until the AutoInitSpan destructor signals that it has finished
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * initialization.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * When this method returns a failure, the caller must not use the object
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * and should return the failed result code to its own caller.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * @param aLimited |true| to add a limited caller.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * @return S_OK on success or E_ACCESSDENIED on failure.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * @sa #releaseCaller()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncHRESULT ObjectState::addCaller(bool aLimited /* = false */)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AutoWriteLock stateLock(mStateLock COMMA_LOCKVAL_SRC_POS);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync HRESULT rc = E_ACCESSDENIED;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mState == Ready || (aLimited && mState == Limited))
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* if Ready or allows Limited, increase the number of callers */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync ++mCallers;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync rc = S_OK;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mState == InInit || mState == InUninit)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mStateChangeThread == RTThreadSelf())
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* Called from the same thread that is doing AutoInitSpan or
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * AutoUninitSpan, just succeed */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync rc = S_OK;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else if (mState == InInit)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* addCaller() is called by a "child" thread while the "parent"
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * thread is still doing AutoInitSpan/AutoReinitSpan, so wait for
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * the state to become either Ready/Limited or InitFailed (in
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * case of init failure).
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Note that we increase the number of callers anyway -- to
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * prevent AutoUninitSpan from early completion if we are
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * still not scheduled to pick up the posted semaphore when
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * uninit() is called.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync ++mCallers;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* lazy semaphore creation */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mInitUninitSem == NIL_RTSEMEVENTMULTI)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventMultiCreate(&mInitUninitSem);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mInitUninitWaiters == 0);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync ++mInitUninitWaiters;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync LogFlowThisFunc(("Waiting for AutoInitSpan/AutoReinitSpan to finish...\n"));
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync stateLock.release();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventMultiWait(mInitUninitSem, RT_INDEFINITE_WAIT);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync stateLock.acquire();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (--mInitUninitWaiters == 0)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* destroy the semaphore since no more necessary */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventMultiDestroy(mInitUninitSem);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mInitUninitSem = NIL_RTSEMEVENTMULTI;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mState == Ready || (aLimited && mState == Limited))
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync rc = S_OK;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mCallers != 0);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync --mCallers;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mCallers == 0 && mState == InUninit)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* inform AutoUninitSpan ctor there are no more callers */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventSignal(mZeroCallersSem);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (FAILED(rc))
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mState == Limited)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync rc = mObj->setError(rc, "The object functionality is limited");
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync rc = mObj->setError(rc, "The object is not ready");
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return rc;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/**
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Decreases the number of calls to this object by one.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Must be called after every #addCaller() when protecting the object
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * from uninitialization is no more necessary.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncvoid ObjectState::releaseCaller()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AutoWriteLock stateLock(mStateLock COMMA_LOCKVAL_SRC_POS);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mState == Ready || mState == Limited)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* if Ready or Limited, decrease the number of callers */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AssertMsgReturn(mCallers != 0, ("mCallers is ZERO!"), (void) 0);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync --mCallers;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mState == InInit || mState == InUninit)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mStateChangeThread == RTThreadSelf())
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* Called from the same thread that is doing AutoInitSpan or
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * AutoUninitSpan: just succeed */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mState == InUninit)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* the caller is being released after AutoUninitSpan has begun */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AssertMsgReturn(mCallers != 0, ("mCallers is ZERO!"), (void) 0);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync --mCallers;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mCallers == 0)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* inform the Auto*UninitSpan ctor there are no more callers */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventSignal(mZeroCallersSem);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AssertMsgFailed(("mState = %d!", mState));
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncbool ObjectState::autoInitSpanConstructor(ObjectState::State aExpectedState)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AutoWriteLock stateLock(mStateLock COMMA_LOCKVAL_SRC_POS);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mState == aExpectedState)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync setState(InInit);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return true;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return false;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncvoid ObjectState::autoInitSpanDestructor(State aNewState)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AutoWriteLock stateLock(mStateLock COMMA_LOCKVAL_SRC_POS);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mState == InInit);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mCallers > 0 && mInitUninitWaiters > 0)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* We have some pending addCaller() calls on other threads (created
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * during InInit), signal that InInit is finished and they may go on. */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventMultiSignal(mInitUninitSem);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync setState(aNewState);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncObjectState::State ObjectState::autoUninitSpanConstructor()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AutoWriteLock stateLock(mStateLock COMMA_LOCKVAL_SRC_POS);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mState != InInit);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mState == NotReady)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* do nothing if already uninitialized */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return mState;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else if (mState == InUninit)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* Another thread has already started uninitialization, wait for its
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * completion. This is necessary to make sure that when this method
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * returns, the object state is well-defined (NotReady). */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* lazy semaphore creation */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mInitUninitSem == NIL_RTSEMEVENTMULTI)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventMultiCreate(&mInitUninitSem);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mInitUninitWaiters == 0);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync ++mInitUninitWaiters;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync LogFlowFunc(("{%p}: Waiting for AutoUninitSpan to finish...\n", mObj));
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync stateLock.release();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventMultiWait(mInitUninitSem, RT_INDEFINITE_WAIT);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync stateLock.acquire();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (--mInitUninitWaiters == 0)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* destroy the semaphore since no more necessary */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventMultiDestroy(mInitUninitSem);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mInitUninitSem = NIL_RTSEMEVENTMULTI;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* the other thread set it to NotReady */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return mState;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* go to InUninit to prevent from adding new callers */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync setState(InUninit);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* wait for already existing callers to drop to zero */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mCallers > 0)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* lazy creation */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mZeroCallersSem == NIL_RTSEMEVENT);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventCreate(&mZeroCallersSem);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* wait until remaining callers release the object */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync LogFlowFunc(("{%p}: Waiting for callers (%d) to drop to zero...\n",
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mObj, mCallers));
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync stateLock.release();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync RTSemEventWait(mZeroCallersSem, RT_INDEFINITE_WAIT);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return mState;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncvoid ObjectState::autoUninitSpanDestructor()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AutoWriteLock stateLock(mStateLock COMMA_LOCKVAL_SRC_POS);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mState == InUninit);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync setState(NotReady);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncvoid ObjectState::setState(ObjectState::State aState)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mState != aState);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mState = aState;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mStateChangeThread = RTThreadSelf();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync////////////////////////////////////////////////////////////////////////////////
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync//
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync// AutoInitSpan methods
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync//
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync////////////////////////////////////////////////////////////////////////////////
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/**
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Creates a smart initialization span object that places the object to
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * InInit state.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Please see the AutoInitSpan class description for more info.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * @param aObj |this| pointer of the managed VirtualBoxBase object whose
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * init() method is being called.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * @param aResult Default initialization result.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncAutoInitSpan::AutoInitSpan(VirtualBoxBase *aObj,
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Result aResult /* = Failed */)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync : mObj(aObj),
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mResult(aResult),
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mOk(false)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mObj);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mOk = mObj->getObjectState().autoInitSpanConstructor(ObjectState::NotReady);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AssertReturnVoid(mOk);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/**
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Places the managed VirtualBoxBase object to Ready/Limited state if the
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * initialization succeeded or partly succeeded, or places it to InitFailed
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * state and calls the object's uninit() method.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Please see the AutoInitSpan class description for more info.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncAutoInitSpan::~AutoInitSpan()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* if the state was other than NotReady, do nothing */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (!mOk)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync ObjectState::State newState;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mResult == Succeeded)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync newState = ObjectState::Ready;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else if (mResult == Limited)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync newState = ObjectState::Limited;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync newState = ObjectState::InitFailed;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mObj->getObjectState().autoInitSpanDestructor(newState);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (newState == ObjectState::InitFailed)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync {
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* call uninit() to let the object uninit itself after failed init() */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mObj->uninit();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* Note: the object may no longer exist here (for example, it can call
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * the destructor in uninit()) */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync }
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync// AutoReinitSpan methods
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync////////////////////////////////////////////////////////////////////////////////
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/**
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Creates a smart re-initialization span object and places the object to
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * InInit state.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Please see the AutoInitSpan class description for more info.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * @param aObj |this| pointer of the managed VirtualBoxBase object whose
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * re-initialization method is being called.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncAutoReinitSpan::AutoReinitSpan(VirtualBoxBase *aObj)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync : mObj(aObj),
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mSucceeded(false),
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mOk(false)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mObj);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mOk = mObj->getObjectState().autoInitSpanConstructor(ObjectState::Limited);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync AssertReturnVoid(mOk);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/**
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Places the managed VirtualBoxBase object to Ready state if the
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * re-initialization succeeded (i.e. #setSucceeded() has been called) or back to
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Limited state otherwise.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Please see the AutoInitSpan class description for more info.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncAutoReinitSpan::~AutoReinitSpan()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* if the state was other than Limited, do nothing */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (!mOk)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync ObjectState::State newState;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mSucceeded)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync newState = ObjectState::Ready;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync newState = ObjectState::Limited;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mObj->getObjectState().autoInitSpanDestructor(newState);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /** @todo r=klaus: this is like the initial init() failure, but in this
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * place uninit() is NOT called. Makes only limited sense. */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync// AutoUninitSpan methods
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync////////////////////////////////////////////////////////////////////////////////
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/**
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Creates a smart uninitialization span object and places this object to
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * InUninit state.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Please see the AutoInitSpan class description for more info.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * @note This method blocks the current thread execution until the number of
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * callers of the managed VirtualBoxBase object drops to zero!
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync *
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * @param aObj |this| pointer of the VirtualBoxBase object whose uninit()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * method is being called.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncAutoUninitSpan::AutoUninitSpan(VirtualBoxBase *aObj)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync : mObj(aObj),
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mInitFailed(false),
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mUninitDone(false)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync Assert(mObj);
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync ObjectState::State state;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync state = mObj->getObjectState().autoUninitSpanConstructor();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (state == ObjectState::InitFailed)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mInitFailed = true;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync else if (state == ObjectState::NotReady)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mUninitDone = true;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync/**
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync * Places the managed VirtualBoxBase object to the NotReady state.
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsyncAutoUninitSpan::~AutoUninitSpan()
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync{
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync /* do nothing if already uninitialized */
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync if (mUninitDone)
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync return;
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync mObj->getObjectState().autoUninitSpanDestructor();
84029357bc8c5780585a1cd1b40319bbc23d022fvboxsync}
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync/**
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync * Marks the uninitializion as succeeded.
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync *
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync * Same as the destructor, and makes the destructor do nothing.
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync */
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsyncvoid AutoUninitSpan::setSucceeded()
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync{
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync /* do nothing if already uninitialized */
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync if (mUninitDone)
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync return;
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync mObj->getObjectState().autoUninitSpanDestructor();
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync mUninitDone = true;
82ae84c8df758538c13cc48d2e569bd8903105d2vboxsync}