VirtualBoxBase.cpp revision f9108665f82b59c99ac444815d75af51a14e46c7
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * VirtualBox COM base classes implementation
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * Copyright (C) 2006-2007 innotek GmbH
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * available from http://www.virtualbox.org. This file is free software;
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * you can redistribute it and/or modify it under the terms of the GNU
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * General Public License (GPL) as published by the Free Software
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync#else // !defined (VBOX_WITH_XPCOM)
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync#endif // !defined (VBOX_WITH_XPCOM)
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync// VirtualBoxBaseNEXT_base methods
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync////////////////////////////////////////////////////////////////////////////////
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync// AutoLock::Lockable interface
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsyncAutoLock::Handle *VirtualBoxBaseNEXT_base::lockHandle() const
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync /* lasy initialization */
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * Increments the number of calls to this object by one.
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * After this method succeeds, it is guaranted that the object will remain in
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * the Ready (or in the Limited) state at least until #releaseCaller() is
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * This method is intended to mark the beginning of sections of code within
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * methods of COM objects that depend on the readiness (Ready) state. The
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * Ready state is a primary "ready to serve" state. Usually all code that
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * works with component's data depends on it. On practice, this means that
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * almost every public method, setter or getter of the object should add
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * itself as an object's caller at the very beginning, to protect from an
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * unexpected uninitialization that may happen on a different thread.
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * Besides the Ready state denoting that the object is fully functional,
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * there is a special Limited state. The Limited state means that the object
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * is still functional, but its functionality is limited to some degree, so
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * not all operations are possible. The @a aLimited argument to this method
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * determines whether the caller represents this limited functionality or not.
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * This method succeeeds (and increments the number of callers) only if the
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * current object's state is Ready. Otherwise, it will return E_UNEXPECTED to
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * indicate that the object is not operational. There are two exceptions from
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * this rule:
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * <li>If the @a aLimited argument is |true|, then this method will also
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * succeeed if the object's state is Limited (or Ready, of course).</li>
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * <li>If this method is called from the same thread that placed the object
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * to InInit or InUninit state (i.e. either from within the AutoInitSpan
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * or AutoUninitSpan scope), it will succeed as well (but will not
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * increase the number of callers).</li>
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * Normally, calling addCaller() never blocks. However, if this method is
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * called by a thread created from within the AutoInitSpan scope and this
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * scope is still active (i.e. the object state is InInit), it will block
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * until the AutoInitSpan destructor signals that it has finished
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * initialization.
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync * When this method returns a failure, the caller must not use the object
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * and can return the failed result code to his caller.
6d73c66200a04223ae56a22ff221ec32193717a5vboxsync * @param aState where to store the current object's state
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * (can be used in overriden methods to determine the
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * cause of the failure)
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * @param aLimited |true| to add a limited caller.
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * @return S_OK on success or E_UNEXPECTED on failure
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * @note It is preferrable to use the #addLimitedCaller() rather than calling
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * this method with @a aLimited = |true|, for better
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * self-descriptiveness.
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * @sa #addLimitedCaller()
75fb03f8c1ac60d0449d333b78ec1ef08fcc9868vboxsync * @sa #releaseCaller()
++ mCallers;
* thread is still doing AutoInitSpan/AutoReadySpan. Wait for the
* state to become either Ready/Limited or InitFailed/InInit/NotReady
++ mCallers;
if (-- mInitDoneSemUsers == 0)
-- mCallers;
if (aState)
return rc;
-- mCallers;
-- mCallers;
if (mCallers == 0)
if (!mOk)
if (!mOk)
if (!mOk)
if (!mOk)
if (mSucceeded)
mInitFailed = true;
if (mUninitDone)
if (mUninitDone)
const char *comment)
return sourceText;
#if defined(DEBUG) && 0
NULL);
if (ok)
NULL);
if (ok)
if (!fn)
#if defined (__GNUC__)
if (start)
bool aPreserve)
#if !defined (VBOX_WITH_XPCOM)
#if defined (RT_OS_WINDOWS)
if (aPreserve)
if (aPreserve)
/// @todo (r=dmik) see todo in VirtualBoxBase.h, in
if (child)
return NULL;
return NULL;
++ mChildrenLeft;
/// @todo (r=dmik) see todo in VirtualBoxBase.h, in
-- mChildrenLeft;
if (mChildrenLeft == 0)
if (child)
return NULL;
return NULL;
++ mChildrenLeft;
-- mChildrenLeft;
if (mChildrenLeft == 0)
aUnk));
mInUninit = true;
if (child)
mInUninit = false;
#if defined VBOX_MAIN_SETTINGS_ADDONS
namespace settings
throw ENoValue();
return result;
return result;
throw ENoValue();
return result;