HRESULT Progress::getInitiator(ComPtr<IUnknown> &aInitiator) { /* mInitiator/mParent are constant during life time, no need to lock */ #if !defined(VBOX_COM_INPROC) if (mInitiator) mInitiator.queryInterfaceTo(aInitiator.asOutParam()); else { ComObjPtr<VirtualBox> pVirtualBox(mParent); pVirtualBox.queryInterfaceTo(aInitiator.asOutParam()); } #else mInitiator.queryInterfaceTo(aInitiator.asOutParam()); #endif return S_OK; }
STDMETHODIMP Progress::COMGETTER(Initiator)(IUnknown **aInitiator) { CheckComArgOutPointerValid(aInitiator); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); /* mInitiator/mParent are constant during life time, no need to lock */ #if !defined(VBOX_COM_INPROC) if (mInitiator) mInitiator.queryInterfaceTo(aInitiator); else { ComObjPtr<VirtualBox> pVirtualBox(mParent); pVirtualBox.queryInterfaceTo(aInitiator); } #else mInitiator.queryInterfaceTo(aInitiator); #endif return S_OK; }
/** * Initializes the normal progress object. With this variant, one can have * an arbitrary number of sub-operation which IProgress can analyze to * have a weighted progress computed. * * For example, say that one IProgress is supposed to track the cloning * of two hard disk images, which are 100 MB and 1000 MB in size, respectively, * and each of these hard disks should be one sub-operation of the IProgress. * * Obviously the progress would be misleading if the progress displayed 50% * after the smaller image was cloned and would then take much longer for * the second half. * * With weighted progress, one can invoke the following calls: * * 1) create progress object with cOperations = 2 and ulTotalOperationsWeight = * 1100 (100 MB plus 1100, but really the weights can be any ULONG); pass * in ulFirstOperationWeight = 100 for the first sub-operation * * 2) Then keep calling setCurrentOperationProgress() with a percentage * for the first image; the total progress will increase up to a value * of 9% (100MB / 1100MB * 100%). * * 3) Then call setNextOperation with the second weight (1000 for the megabytes * of the second disk). * * 4) Then keep calling setCurrentOperationProgress() with a percentage for * the second image, where 100% of the operation will then yield a 100% * progress of the entire task. * * Weighting is optional; you can simply assign a weight of 1 to each operation * and pass ulTotalOperationsWeight == cOperations to this constructor (but * for that variant and for backwards-compatibility a simpler constructor exists * in ProgressImpl.h as well). * * Even simpler, if you need no sub-operations at all, pass in cOperations = * ulTotalOperationsWeight = ulFirstOperationWeight = 1. * * @param aParent Parent object (only for server-side Progress objects). * @param aInitiator Initiator of the task (for server-side objects. Can be * NULL which means initiator = parent, otherwise must not * be NULL). * @param aDescription Overall task description. * @param aCancelable Flag whether the task maybe canceled. * @param cOperations Number of operations within this task (at least 1). * @param ulTotalOperationsWeight Total weight of operations; must be the sum of ulFirstOperationWeight and * what is later passed with each subsequent setNextOperation() call. * @param bstrFirstOperationDescription Description of the first operation. * @param ulFirstOperationWeight Weight of first sub-operation. */ HRESULT Progress::init( #if !defined(VBOX_COM_INPROC) VirtualBox *aParent, #endif IUnknown *aInitiator, Utf8Str aDescription, BOOL aCancelable, ULONG cOperations, ULONG ulTotalOperationsWeight, Utf8Str aFirstOperationDescription, ULONG ulFirstOperationWeight) { LogFlowThisFunc(("aDescription=\"%s\", cOperations=%d, ulTotalOperationsWeight=%d, aFirstOperationDescription=\"%s\", ulFirstOperationWeight=%d\n", aDescription.c_str(), cOperations, ulTotalOperationsWeight, aFirstOperationDescription.c_str(), ulFirstOperationWeight)); AssertReturn(ulTotalOperationsWeight >= 1, E_INVALIDARG); /* Enclose the state transition NotReady->InInit->Ready */ AutoInitSpan autoInitSpan(this); AssertReturn(autoInitSpan.isOk(), E_FAIL); HRESULT rc = S_OK; // rc = Progress::init( //#if !defined(VBOX_COM_INPROC) // aParent, //#endif // aInitiator, aDescription, FALSE, aId); // NA #if !defined(VBOX_COM_INPROC) AssertReturn(aParent, E_INVALIDARG); #else AssertReturn(aInitiator, E_INVALIDARG); #endif #if !defined(VBOX_COM_INPROC) /* share parent weakly */ unconst(mParent) = aParent; #endif #if !defined(VBOX_COM_INPROC) /* assign (and therefore addref) initiator only if it is not VirtualBox * (to avoid cycling); otherwise mInitiator will remain null which means * that it is the same as the parent */ if (aInitiator) { ComObjPtr<VirtualBox> pVirtualBox(mParent); if (!(pVirtualBox == aInitiator)) unconst(mInitiator) = aInitiator; } #else unconst(mInitiator) = aInitiator; #endif unconst(mId).create(); #if !defined(VBOX_COM_INPROC) /* add to the global collection of progress operations (note: after * creating mId) */ mParent->i_addProgress(this); #endif unconst(mDescription) = aDescription; // end of assertion if (FAILED(rc)) return rc; mCancelable = aCancelable; m_cOperations = cOperations; m_ulTotalOperationsWeight = ulTotalOperationsWeight; m_ulOperationsCompletedWeight = 0; m_ulCurrentOperation = 0; m_operationDescription = aFirstOperationDescription; m_ulCurrentOperationWeight = ulFirstOperationWeight; m_ulOperationPercent = 0; int vrc = RTSemEventMultiCreate(&mCompletedSem); ComAssertRCRet(vrc, E_FAIL); RTSemEventMultiReset(mCompletedSem); /* Confirm a successful initialization when it's the case */ if (SUCCEEDED(rc)) autoInitSpan.setSucceeded(); return rc; }