VirtualBoxBase.h revision 156c3838b0c2a078d5652a6d9e3526526f779be0
"Please contact the product vendor!", \
* A special version of the AssertMsgFailed macro to be used within VirtualBoxBase * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template. * See ComAssert for more info. * @param a printf argument list (in parenthesis). "Please contact the product vendor!", \
* A special version of the AssertComRC macro to be used within VirtualBoxBase * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template. * See ComAssert for more info. * @param rc COM result code /** Special version of ComAssert that returns ret if expr fails */ /** Special version of ComAssertMsg that returns ret if expr fails */ /** Special version of ComAssertRC that returns ret if vrc does not succeed */ /** Special version of ComAssertMsgRC that returns ret if vrc does not succeed */ /** Special version of ComAssertFailed that returns ret */ /** Special version of ComAssertMsgFailed that returns ret */ /** Special version of ComAssertComRC that returns ret if rc does not succeed */ /** Special version of ComAssertComRC that returns rc if rc does not succeed */ /** Special version of ComAssert that evaulates eval and breaks if expr fails */ /** Special version of ComAssertMsg that evaulates eval and breaks if expr fails */ /** Special version of ComAssertRC that evaulates eval and breaks if vrc does not succeed */ /** Special version of ComAssertMsgRC that evaulates eval and breaks if vrc does not succeed */ /** Special version of ComAssertFailed that evaulates eval and breaks */ /** Special version of ComAssertMsgFailed that evaulates eval and breaks */ /** Special version of ComAssertComRC that evaulates eval and breaks if rc does not succeed */ /** Special version of ComAssertComRC that just breaks if rc does not succeed */ /// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely * Checks whether this object is ready or not. Objects are typically ready * after they are successfully created by their parent objects and become * not ready when the respective parent itsef becomes not ready or gets * destroyed while a reference to the child is still held by the caller * (which prevents it from destruction). * When this object is not ready, the macro sets error info and returns * E_UNEXPECTED (the translatable error message is defined in null context). * Otherwise, the macro does nothing. * This macro <b>must</b> be used at the beginning of all interface methods * (right after entering the class lock) in classes derived from both * VirtualBoxBase and VirtualBoxSupportErrorInfoImpl. * Declares an empty construtor and destructor for the given class. * This is useful to prevent the compiler from generating the default * ctor and dtor, which in turn allows to use forward class statements * (instead of including their header files) when declaring data members of * non-fundamental types with constructors (which are always called implicitly * by constructors and by the destructor of the class). * This macro is to be palced within (the public section of) the class * declaration. Its counterpart, DEFINE_EMPTY_CTOR_DTOR, must be placed * somewhere in one of the translation units (usually .cpp source files). * @param cls class to declare a ctor and dtor for * Defines an empty construtor and destructor for the given class. * See DECLARE_EMPTY_CTOR_DTOR for more info. //////////////////////////////////////////////////////////////////////////////// * A wrapper around the container that owns pointers it stores. * Ownership is recognized only when destructing the container! * Pointers are not deleted when erased using erase() etc. * class that meets Container requirements (for example, an instance of * std::list<>, std::vector<> etc.). The given class must store * pointers (for example, std::list <MyType *>). //////////////////////////////////////////////////////////////////////////////// // AutoLock::Lockable interface * Virtual unintialization method. * Must be called by all implementations (COM classes) when the last * reference to the object is released, before calling the destructor. * Also, this method is called automatically by the uninit() method of the * parent of this object, when this object is a dependent child of a class * derived from VirtualBoxBaseWithChildren (@sa * VirtualBoxBaseWithChildren::addDependentChild). * Adds a limited caller. This method is equivalent to doing * <tt>addCaller (aState, true)</tt>, but it is preferred because * provides better self-descriptiveness. See #addCaller() for more info. * Smart class that automatically increases the number of callers of the * given VirtualBoxBase object when an instance is constructed and decreases * it back when the created instance goes out of scope (i.e. gets destroyed). * If #rc() returns a failure after the instance creation, it means that * the managed VirtualBoxBase object is not Ready, or in any other invalid * state, so that the caller must not use the object and can return this * failed result code to the upper level. * See VirtualBoxBase::addCaller(), VirtualBoxBase::addLimitedCaller() and * VirtualBoxBase::releaseCaller() for more details about object callers. * @param aLimited |false| if this template should use * VirtualiBoxBase::addCaller() calls to add callers, or * |true| if VirtualiBoxBase::addLimitedCaller() should be * @note It is preferrable to use the AutoCaller and AutoLimitedCaller * classes than specify the @a aLimited argument, for better * Increases the number of callers of the given object * by calling VirtualBoxBase::addCaller(). * If the number of callers was successfully increased, * decreases it using VirtualBoxBase::releaseCaller(), otherwise * Stores the result code returned by VirtualBoxBase::addCaller() * after instance creation or after the last #add() call. A successful * result code means the number of callers was successfully increased. * Returns |true| if |SUCCEEDED (rc())| is |true|, for convenience. * |true| means the number of callers was successfully increased. * Stores the object state returned by VirtualBoxBase::addCaller() * after instance creation or after the last #add() call. * Temporarily decreases the number of callers of the managed object. * May only be called if #isOk() returns |true|. Note that #rc() will * return E_FAIL after this method succeeds. * Restores the number of callers decreased by #release(). May only * be called after #release(). * Smart class that automatically increases the number of normal * (non-limited) callers of the given VirtualBoxBase object when an * instance is constructed and decreases it back when the created instance * goes out of scope (i.e. gets destroyed). * A typical usage pattern to declare a normal method of some object * (i.e. a method that is valid only when the object provides its * full functionality) is: * STDMETHODIMP Component::Foo() * AutoCaller autoCaller (this); * CheckComRCReturnRC (autoCaller.rc()); * Using this class is equivalent to using the AutoCallerBase template * with the @a aLimited argument set to |false|, but this class is * preferred because provides better self-descriptiveness. * See AutoCallerBase for more information about auto caller functionality. * Smart class that automatically increases the number of limited callers * of the given VirtualBoxBase object when an instance is constructed and * decreases it back when the created instance goes out of scope (i.e. * A typical usage pattern to declare a limited method of some object * (i.e. a method that is valid even if the object doesn't provide its * full functionality) is: * STDMETHODIMP Component::Bar() * AutoLimitedCaller autoCaller (this); * CheckComRCReturnRC (autoCaller.rc()); * Using this class is equivalent to using the AutoCallerBase template * with the @a aLimited argument set to |true|, but this class is * preferred because provides better self-descriptiveness. * See AutoCallerBase for more information about auto caller functionality. * Smart class to enclose the state transition NotReady->InInit->Ready. * Instances must be created at the beginning of init() methods of * VirtualBoxBase subclasses as a stack-based variable using |this| pointer * as the argument. When this variable is created it automatically places * the object to the InInit state. * When the created variable goes out of scope (i.e. gets destroyed), * depending on the success status of this initialization span, it either * places the object to the Ready state or calls the object's * VirtualBoxBase::uninit() method which is supposed to place the object * back to the NotReady state using the AutoUninitSpan class. * The initial success status of the initialization span is determined by * the @a aSuccess argument of the AutoInitSpan constructor (|false| by * default). Inside the initialization span, the success status can be set * to |true| using #setSucceeded() or to |false| using #setFailed(). Please * don't forget to set the correct success status before letting the * AutoInitSpan variable go out of scope (for example, by performing an * early return from the init() method)! * Note that if an instance of this class gets constructed when the * object is in the state other than NotReady, #isOk() returns |false| and * methods of this class do nothing: the state transition is not performed. * A typical usage pattern is: * HRESULT Component::init() * AutoInitSpan autoInitSpan (this); * AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED); * @note Never create instances of this class outside init() methods of * VirtualBoxBase subclasses and never pass anything other than |this| as * the argument to the constructor! * Returns |true| if this instance has been created at the right moment * (when the object was in the NotReady state) and |false| otherwise. * Sets the initialization status to Succeeded to indicates successful * initialization. The AutoInitSpan destructor will place the managed * VirtualBoxBase object to the Ready state. * Sets the initialization status to Succeeded to indicate limited * (partly successful) initialization. The AutoInitSpan destructor will * place the managed VirtualBoxBase object to the Limited state. * Sets the initialization status to Failure to indicates failed * initialization. The AutoInitSpan destructor will place the managed * VirtualBoxBase object to the InitFailed state and will automatically * call its uninit() method which is supposed to place the object back * to the NotReady state using AutoUninitSpan. /** Returns the current initialization status. */ Status mStatus :
3;
// must be at least total number of bits + 1 (sign) * Smart class to enclose the state transition Limited->InInit->Ready. * Instances must be created at the beginning of methods of VirtualBoxBase * subclasses that try to re-initialize the object to bring it to the * Ready state (full functionality) after partial initialization * (limited functionality)>, as a stack-based variable using |this| pointer * as the argument. When this variable is created it automatically places * the object to the InInit state. * When the created variable goes out of scope (i.e. gets destroyed), * depending on the success status of this initialization span, it either * places the object to the Ready state or brings it back to the Limited * The initial success status of the re-initialization span is |false|. * In order to make it successful, #setSucceeded() must be called before * the instance is destroyed. * Note that if an instance of this class gets constructed when the * object is in the state other than Limited, #isOk() returns |false| and * methods of this class do nothing: the state transition is not performed. * A typical usage pattern is: * HRESULT Component::reinit() * AutoReadySpan autoReadySpan (this); * AssertReturn (autoReadySpan.isOk(), E_UNEXPECTED); * @note Never create instances of this class outside re-initialization * methods of VirtualBoxBase subclasses and never pass anything other than * |this| as the argument to the constructor! * Returns |true| if this instance has been created at the right moment * (when the object was in the Limited state) and |false| otherwise. * Sets the re-initialization status to Succeeded to indicates * successful re-initialization. The AutoReadySpan destructor will * place the managed VirtualBoxBase object to the Ready state. * Smart class to enclose the state transition Ready->InUnnit->NotReady or * InitFailed->InUnnit->NotReady. * Must be created at the beginning of uninit() methods of VirtualBoxBase * subclasses as a stack-based variable using |this| pointer as the argument. * When this variable is created it automatically places the object to the * InUninit state, unless it is already in the NotReady state as indicated * by #uninitDone() returning |true|. In the latter case, the uninit() * method must immediately return because there should be nothing to * When this variable goes out of scope (i.e. gets destroyed), it places * the object to the NotReady state. * A typical usage pattern is: * void Component::uninit() * AutoUninitSpan autoUninitSpan (this); * if (autoUninitSpan.uninitDone()) * @note Never create instances of this class outside uninit() methods and * never pass anything other than |this| as the argument to the constructor! /** |true| when uninit() is called as a result of init() failure */ /** |true| when uninit() has already been called (so the object is NotReady) */ /** Primary state of this object */ /** Thread that caused the last state change */ /** Total number of active calls to this object */ /** Semaphore posted when the number of callers drops to zero */ /** Semaphore posted when the object goes from InInit some other state */ /** Number of threads waiting for mInitDoneSem */ /** Protects access to state related data members */ /** User-level object lock for subclasses */ * This macro adds the error info support to methods of the VirtualBoxBase * class (by overriding them). Place it to the public section of the * VirtualBoxBase subclass and the following methods will set the extended * error info in case of failure instead of just returning the result code: * <li>VirtualBoxBase::addCaller() * @note The given VirtualBoxBase subclass must also inherit from both * VirtualBoxSupportErrorInfoImpl and VirtualBoxSupportTranslation templates! * @param C VirtualBoxBase subclass to add the error info support to //////////////////////////////////////////////////////////////////////////////// /// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely // : public CComObjectRootEx<CComMultiThreadModel> // : public CComObjectRootEx * Virtual unintialization method. Called during parent object's * uninitialization, if the given subclass instance is a dependent child of * a class dervived from VirtualBoxBaseWithChildren (@sa * VirtualBoxBaseWithChildren::addDependentChild). In this case, this * method's impelemtation must call setReady (false), // sets the ready state of the object // get the ready state of the object // flag determining whether an object is ready // for usage, i.e. methods may be called // mutex semaphore to lock the object * Temporary class to disable deprecated methods of VirtualBoxBase. * Can be used as a base for components that are completely switched to * the new locking scheme (VirtualBoxBaseNEXT_base). * @todo remove after we switch to VirtualBoxBaseNEXT completely. //////////////////////////////////////////////////////////////////////////////// /** Helper for VirtualBoxSupportTranslation */ * This template implements the NLS string translation support for the * given class by providing a #tr() function. * @param C class that needs to support the string translation * Every class that wants to use the #tr() function in its own methods must * inherit from this template, regardless of whether its base class (if any) * inherits from it or not! Otherwise, the translation service will not * work correctly. However, the declaration of the resulting class must * contain the VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE(<ClassName>) macro * if one of its base classes also inherits from this template (to resolve * the ambiguity of the #tr() function). * Translates the given text string according to the currently installed * translation table and current context, which is determined by the * class name. See VirtualBoxBase::translate() for more info. * @param sourceText the string to translate * @param comment the comment to the string (NULL means no comment) * the translated version of the source string in UTF-8 encoding, * or the source string itself if the translation is not found in * This macro must be invoked inside the public section of the declaration of * the class inherited from the VirtualBoxSupportTranslation template, in case * when one of its other base classes also inherits from that template. This is * necessary to resolve the ambiguity of the #tr() function. * @param C class that inherits from the VirtualBoxSupportTranslation template * more than once (through its other base clases) * A dummy macro that is used to shut down Qt's lupdate tool warnings * in some situations. This macro needs to be present inside (better at the * very beginning) of the declaration of the class that inherits from * VirtualBoxSupportTranslation template, to make lupdate happy. //////////////////////////////////////////////////////////////////////////////// * Helper for the VirtualBoxSupportErrorInfoImpl template. * This template implements ISupportErrorInfo for the given component class * and provides the #setError() method to conveniently set the error information * from within interface methods' implementations. * On Windows, the template argument must define a COM interface map using * BEGIN_COM_MAP / END_COM_MAP macros and this map must contain a * COM_INTERFACE_ENTRY(ISupportErrorInfo) definition. All interface entries * that follow it will be considered to support IErrorInfo, i.e. the * InterfaceSupportsErrorInfo() implementation will return S_OK for the * On all platforms, the template argument must also define the following * method: |public static const wchar_t *C::getComponentName()|. See * #setError (HRESULT, const char *, ...) for a description on how it is * component class that implements one or more COM interfaces * default interface for the component. This interface's IID is used * by the shortest form of #setError, for convenience. // skip the com map entries until ISupportErrorInfo is found // look for the requested interface in the rest of the com map #
endif // defined (__WIN__) * Sets the error information for the current thread. * This information can be retrieved by a caller of an interface method * using IErrorInfo on Windows or nsIException on Linux, or the cross-platform * IVirtualBoxErrorInfo interface that provides extended error info (only * for components from the VirtualBox COM library). Alternatively, the * platform-independent class com::ErrorInfo (defined in VBox[XP]COM.lib) * can be used to retrieve error info in a convenient way. * It is assumed that the interface method that uses this function returns * an unsuccessful result code to the caller (otherwise, there is no reason * for the caller to try to retrieve error info after method invocation). * Here is a table of correspondence between this method's arguments * argument IErrorInfo nsIException IVirtualBoxErrorInfo * ---------------------------------------------------------------- * resultCode -- result resultCode * iid GetGUID -- interfaceID * component GetSource -- component * text GetDescription message text * This method is rarely needs to be used though. There are more convenient * overloaded versions, that automatically substitute some arguments * taking their values from the template parameters. See * #setError (HRESULT, const char *, ...) for an example. * @param resultCode result (error) code, must not be S_OK * @param iid IID of the intrface that defines the error * @param component name of the component that generates the error * @param text error message (must not be null), an RTStrPrintf-like * format string in UTF-8 encoding * @param ... list of arguments for the format string * the error argument, for convenience, If an error occures while * creating error info itself, that error is returned instead of the * Sets the error information for the current thread. * A convenience method that automatically sets the default interface * ID (taken from the I template argument) and the component name * (a value of C::getComponentName()). * See #setError (HRESULT, const GUID &, const wchar_t *, const char *text, ...) * This method is the most common (and convenient) way to set error * information from within interface methods. A typical pattern of usage * return setError (E_FAIL, "Terrible Error"); * HRESULT rc = setError (E_FAIL, "Terrible Error"); * Sets the error information for the current thread, va_list variant. * A convenience method that automatically sets the default interface * ID (taken from the I template argument) and the component name * (a value of C::getComponentName()). * See #setError (HRESULT, const GUID &, const wchar_t *, const char *text, ...) * and #setError (HRESULT, const char *, ...) for details. * Sets the error information for the current thread, BStr variant. * A convenience method that automatically sets the default interface * ID (taken from the I template argument) and the component name * (a value of C::getComponentName()). * This method is preferred iy you have a ready (translated and formatted) * Bstr string, because it omits an extra conversion Utf8Str -> Bstr. * See #setError (HRESULT, const GUID &, const wchar_t *, const char *text, ...) * and #setError (HRESULT, const char *, ...) for details. * Sets the error information for the current thread. * A convenience method that automatically sets the component name * (a value of C::getComponentName()), but allows to specify the interface * See #setError (HRESULT, const GUID &, const wchar_t *, const char *text, ...) * Sets the error information for the current thread using the error * information previously fetched using an ErrorInfo instance. * This is useful, for instance, if you want to keep the error information * returned by some interface's method, but need to call another method * of some interface prior to returning from your method (calling * another method will normally reset the current error information). //////////////////////////////////////////////////////////////////////////////// * Base class to track VirtualBoxBase chlidren of the component. * This class is a preferrable VirtualBoxBase replacement for components * that operate with collections of child components. It gives two useful * Given an IUnknown instance, it's possible to quickly determine * whether this instance represents a child object created by the given * component, and if so, get a valid VirtualBoxBase pointer to the child * object. The returned pointer can be then safely casted to the * actual class of the child object (to get access to its "internal" * non-interface methods) provided that no other child components implement * the same initial interface IUnknown is queried from. * When the parent object uninitializes itself, it can easily unintialize * all its VirtualBoxBase derived children (using their * VirtualBoxBase::uninit() implementations). This is done simply by * calling the #uninitDependentChildren() method. * In order to let the above work, the following must be done: * When a child object is initialized, it calls #addDependentChild() of * its parent to register itself within the list of dependent children. * When a child object it is uninitialized, it calls #removeDependentChild() * to unregister itself. This must be done <b>after</b> the child has called * setReady(false) to indicate it is no more valid, and <b>not</b> from under * the child object's lock. Note also, that the first action the child's * uninit() implementation must do is to check for readiness after acquiring * the object's lock and return immediately if not ready. * Children added by #addDependentChild() are <b>weakly</b> referenced * (i.e. AddRef() is not called), so when a child is externally destructed * (i.e. its reference count goes to zero), it will automatically remove * itself from a map of dependent children, provided that it follows the * Because of weak referencing, deadlocks and assertions are very likely * if #addDependentChild() or #removeDependentChild() are used incorrectly * (called at inappropriate times). Check the above rules once more. * Adds the given child to the map of dependent children. * Intended to be called from the child's init() method, * from under the child's lock. * @param C the child object to add (must inherit VirtualBoxBase AND * implement some interface) * Removes the given child from the map of dependent children. * Must be called <b>after<b> the child has called setReady(false), and * <b>not</b> from under the child object's lock. * @param C the child object to remove (must inherit VirtualBoxBase AND * implement some interface) /// @todo (r=dmik) the below check (and the relevant comment above) // seems to be not necessary any more once we completely switch to // the NEXT locking scheme. This requires altering removeDependentChild() // and uninitDependentChildren() as well (due to the new state scheme, // there is a separate mutex for state transition, so calling the // child's uninit() from under the children map lock should not produce * Temporary class to disable deprecated methods of VirtualBoxBase. * Can be used as a base for components that are completely switched to * the new locking scheme (VirtualBoxBaseNEXT_base). * @todo remove after we switch to VirtualBoxBaseNEXT completely. //////////////////////////////////////////////////////////////////////////////// * Base class to track component's chlidren of some particular type. * This class is similar to VirtualBoxBaseWithChildren, with the exception * that all children must be of the same type. For this reason, it's not * necessary to use a map to store children, so a list is used instead. * As opposed to VirtualBoxBaseWithChildren, children added by * #addDependentChild() are <b>strongly</b> referenced, so that they cannot * be externally destructed until #removeDependentChild() is called. * For this reason, strict rules of calling #removeDependentChild() don't * apply to instances of this class -- it can be called anywhere in the * child's uninit() implementation. * @param C type of child objects (must inherit VirtualBoxBase AND * implement some interface) * Adds the given child to the list of dependent children. * Must be called from the child's init() method, * from under the child's lock. * @param C the child object to add (must inherit VirtualBoxBase AND * implement some interface) * Removes the given child from the list of dependent children. * Must be called from the child's uninit() method, * under the child's lock. * @param C the child object to remove (must inherit VirtualBoxBase AND * implement some interface) * Returns an internal lock handle to lock the list of children * returned by #dependentChildren() using AutoLock: * AutoLock alock (dependentChildrenLock()); * Returns the read-only list of all dependent children. * Access the returned list (iterate, get size etc.) only after * doing |AutoLock alock (dependentChildrenLock());|! * Uninitializes all dependent children registered with #addDependentChild(). * This method will call uninit() methods of children. If these methods * access the parent object, uninitDependentChildren() must be called * either at the beginning of the parent uninitialization sequence (when * it is still operational) or after setReady(false) is called to * indicate the parent is out of action. // set flag to ignore #removeDependentChild() called from child->uninit() // leave the locks to let children waiting for #removeDependentChild() run * Removes (detaches) all dependent children registered with * #addDependentChild(), without uninitializing them. * @note This method must be called from under the main object's lock * Temporary class to disable deprecated methods of VirtualBoxBase. * Can be used as a base for components that are completely switched to * the new locking scheme (VirtualBoxBaseNEXT_base). * @todo remove after we switch to VirtualBoxBaseNEXT completely. //////////////////////////////////////////////////////////////////////////////// /// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely * and supports data pointer sharing (the instance that shares the pointer is * not responsible for memory deallocation as opposed to the instance that (
"new data must not be shared")
/// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely * Simple template that enhances Shareable<> and supports data * Stores the current data pointer in the backup area, allocates new data * using the copy constructor on current data and makes new data active. * Deletes new data created by #backup() and restores previous data pointer * stored in the backup area, making it active again. * Commits current changes by deleting backed up data and clearing up the * backup area. The new data pointer created by #backup() remains active * and becomes the only managed pointer. * This method is much faster than #commitCopy() (just a single pointer * assignment operation), but makes the previous data pointer invalid * (because it is freed). For this reason, this method must not be * used if it's possible that data managed by this instance is shared with * some other Shareable instance. See #commitCopy(). * Commits current changes by assigning new data to the previous data * pointer stored in the backup area using the assignment operator. * New data is deleted, the backup area is cleared and the previous data * pointer becomes active and the only managed pointer. * This method is slower than #commit(), but it keeps the previous data * pointer valid (i.e. new data is copied to the same memory location). * For that reason it's safe to use this method on instances that share * managed data with other Shareable instances. #
endif // ____H_VIRTUALBOXBASEIMPL