VirtualBoxBase.cpp revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
0N/A * VirtualBox COM base classes implementation 2362N/A * Copyright (C) 2006 InnoTek Systemberatung GmbH 2362N/A * This file is part of VirtualBox Open Source Edition (OSE), as 0N/A * you can redistribute it and/or modify it under the terms of the GNU 0N/A * General Public License as published by the Free Software Foundation, 0N/A * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE 0N/A * distribution. VirtualBox OSE is distributed in the hope that it will 0N/A * be useful, but WITHOUT ANY WARRANTY of any kind. 0N/A * If you received this file as part of a commercial VirtualBox 0N/A * distribution, then only the terms of your commercial VirtualBox 0N/A * license agreement apply instead of the previous paragraph. 0N/A#
else // !defined (__WIN__) 0N/A// VirtualBoxBaseNEXT_base methods 0N/A//////////////////////////////////////////////////////////////////////////////// 0N/A// AutoLock::Lockable interface 0N/A /* lasy initialization */ * Increments the number of calls to this object by one. * After this method succeeds, it is guaranted that the object will remain in * the Ready (or in the Limited) state at least until #releaseCaller() is * This method is intended to mark the beginning of sections of code within * methods of COM objects that depend on the readiness (Ready) state. The * Ready state is a primary "ready to serve" state. Usually all code that * works with component's data depends on it. On practice, this means that * almost every public method, setter or getter of the object should add * itself as an object's caller at the very beginning, to protect from an * unexpected uninitialization that may happen on a different thread. * Besides the Ready state denoting that the object is fully functional, * there is a special Limited state. The Limited state means that the object * is still functional, but its functionality is limited to some degree, so * not all operations are possible. The @a aLimited argument to this method * determines whether the caller represents this limited functionality or not. * This method succeeeds (and increments the number of callers) only if the * current object's state is Ready. Otherwise, it will return E_UNEXPECTED to * indicate that the object is not operational. There are two exceptions from * <li>If the @a aLimited argument is |true|, then this method will also * succeeed if the object's state is Limited (or Ready, of course).</li> * <li>If this method is called from the same thread that placed the object * to InInit or InUninit state (i.e. either from within the AutoInitSpan * or AutoUninitSpan scope), it will succeed as well (but will not * increase the number of callers).</li> * Normally, calling addCaller() never blocks. However, if this method is * called by a thread created from within the AutoInitSpan scope and this * scope is still active (i.e. the object state is InInit), it will block * until the AutoInitSpan destructor signals that it has finished * When this method returns a failure, the caller must not use the object * and can return the failed result code to his caller. * @param aState where to store the current object's state * (can be used in overriden methods to determine the * @param aLimited |true| to add a limited caller. * @return S_OK on success or E_UNEXPECTED on failure * @note It is preferrable to use the #addLimitedCaller() rather than calling * this method with @a aLimited = |true|, for better * @sa #addLimitedCaller() /* if Ready or allows Limited, increase the number of callers */ * Called from the same thread that is doing AutoInitSpan or * AutoUninitSpan, just succeed /* addCaller() is called by a "child" thread while the "parent" * (in case of init failure). Note that we increase the number of * callers anyway to prevent AutoUninitSpan from early completion. /* destroy the semaphore since no more necessary */ /* inform AutoUninitSpan ctor there are no more callers */ * Decrements the number of calls to this object by one. * Must be called after every #addCaller() or #addLimitedCaller() when the * object is no more necessary. /* if Ready or Limited, decrease the number of callers */ * Called from the same thread that is doing AutoInitSpan or * AutoUninitSpan, just succeed /* the caller is being released after AutoUninitSpan has begun */ /* inform the AutoUninitSpan ctor there are no more callers */ // VirtualBoxBaseNEXT_base::AutoInitSpan methods //////////////////////////////////////////////////////////////////////////////// * Creates a smart initialization span object and places the object to * @param aObj |this| pointer of the managed VirtualBoxBase object whose * init() method is being called * @param aStatus initial initialization status for this span * Places the managed VirtualBoxBase object to Ready/Limited state if the * initialization succeeded or partly succeeded, or places it to InitFailed * state and calls the object's uninit() method otherwise. /* if the state was other than NotReady, do nothing */ /* We have some pending addCaller() calls on other threads (created * during InInit), signal that InInit is finished. */ /* leave the lock to prevent nesting when uninit() is called */ /* call uninit() to let the object uninit itself after failed init() */ /* Note: the object may no longer exist here (for example, it can call * the destructor in uninit()) */ // VirtualBoxBaseNEXT_base::AutoReadySpan methods //////////////////////////////////////////////////////////////////////////////// * Creates a smart re-initialization span object and places the object to * @param aObj |this| pointer of the managed VirtualBoxBase object whose * re-initialization method is being called * Places the managed VirtualBoxBase object to Ready state if the * re-initialization succeeded (i.e. #setSucceeded() has been called) or * back to Limited state otherwise. /* if the state was other than Limited, do nothing */ /* We have some pending addCaller() calls on other threads, * signal that InInit is finished. */ // VirtualBoxBaseNEXT_base::AutoUninitSpan methods //////////////////////////////////////////////////////////////////////////////// * Creates a smart uninitialization span object and places this object to * @note This method blocks the current thread execution until the number of * callers of the managed VirtualBoxBase object drops to zero! * @param aObj |this| pointer of the VirtualBoxBase object whose uninit() * Set mUninitDone to |true| if this object is already uninitialized * (NotReady) or if another AutoUninitSpan is currently active on some * other thread (InUninit). /* we've been called by init() on failure */ /* do nothing if already uninitialized */ /* go to InUninit to prevent from adding new callers */ /* wait until remaining callers release the object */ * Places the managed VirtualBoxBase object to the NotReady state. /* do nothing if already uninitialized */ // VirtualBoxBase methods //////////////////////////////////////////////////////////////////////////////// * Translates the given text string according to the currently installed * translation table and current context. The current context is determined * by the context parameter. Additionally, a comment to the source text * string text can be given. This comment (which is NULL by default) * is helpful in sutuations where it is necessary to distinguish between * two or more semantically different roles of the same source text in the * @param context the context of the the translation (can be NULL * to indicate the global context) * @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 // Log(("VirtualBoxBase::translate:\n" // context, sourceText, comment)); /// @todo (dmik) incorporate Qt translation file parsing and lookup // Using StackWalk() is not necessary here once we have ASMReturnAddress(). "AutoLock::lock()/enter() return address >>>", 0,
// sanity check of the returned stack frame // get the stack frame of our caller which is either // sanity check of the returned stack frame // the return address here should be the code where lock() or enter() // has been called from (to be more precise, where it will return) "AutoLock::lock()/enter() return address >>>", 0,
#
endif // defined(__LINUX__)// VirtualBoxSupportTranslationBase methods //////////////////////////////////////////////////////////////////////////////// * Modifies the given argument so that it will contain only a class name * (null-terminated). The argument must point to a <b>non-constant</b> * string containing a valid value, as it is generated by the * __PRETTY_FUNCTION__ built-in macro of the GCC compiler, or by the * __FUNCTION__ macro of any other compiler. * The function assumes that the macro is used within the member of the * class derived from the VirtualBoxSupportTranslation<> template. * @param prettyFunctionName string to modify * true on success and false otherwise // VirtualBoxSupportTranslation<C>::VirtualBoxSupportTranslation() [with C = VirtualBox] // VirtualBoxSupportTranslation<class VirtualBox>::__ctor // VirtualBoxSupportErrorInfoImplBase methods //////////////////////////////////////////////////////////////////////////////// LogRel ((
"ERROR [COM]: rc=%#08x IID={%Vuuid} component={%ls} text={%ls}\n",
/* these are mandatory, others -- not */ #
else // !defined (__WIN__) * It is possible that setError() is being called by the object * after the XPCOM shutdown sequence has been initiated * (for example, when XPCOM releases all instances it internally * references, which can cause object's FinalConstruct() and then * uninit()). In this case, do_GetService() above will return * NS_ERROR_UNEXPECTED and it doesn't actually make sense to * set the exception (nobody will be able to read it). "nsIExceptionService is not available " "(NS_ERROR_UNEXPECTED). " "XPCOM is being shutdown?\n"));
#
endif // !defined (__WIN__)// VirtualBoxBaseWithChildren methods //////////////////////////////////////////////////////////////////////////////// * 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. // template <class C> void removeDependentChild (C *child) /* We keep the lock until we have enumerated all children. * Those ones that will try to call #removeDependentChild() from * a different thread will have to wait */ /* Wait until all children started uninitializing on their own * (and therefore are waiting for some parent's method or for * #removeDependentChild() to return) are finished uninitialization */ /* let stuck children run */ * Returns a pointer to the dependent child corresponding to the given * interface pointer (used as a key in the map) or NULL if the interface * pointer doesn't correspond to any child registered using * Pointer to map to the dependent child object (it is ComPtr <IUnknown> * rather than IUnknown *, to guarantee IUnknown * identity) * Pointer to the dependent child object /** Helper for addDependentChild() template method */ // for this very unlikely case, we have to increase the number of // children left, for symmetry with #removeDependentChild() /** Helper for removeDependentChild() template method */ // template <class C> void removeDependentChild (C *child) // uninitDependentChildren() is in action, just increase the number // of children left and signal a semaphore when it reaches zero