ProgressImpl.cpp revision 4c13f0d619c9707412b40eae8e3beafae5cf1858
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * VirtualBox Progress COM class implementation
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * Copyright (C) 2006-2009 Oracle Corporation
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * available from http://www.virtualbox.org. This file is free software;
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * you can redistribute it and/or modify it under the terms of the GNU
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * General Public License (GPL) as published by the Free Software
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync#endif /* defined (VBOX_WITH_XPCOM) */
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync////////////////////////////////////////////////////////////////////////////////
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync// ProgressBase class
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync////////////////////////////////////////////////////////////////////////////////
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync// constructor / destructor
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync////////////////////////////////////////////////////////////////////////////////
76f5d3db08b007661ae4af93200838d24683af52vboxsync * Subclasses must call this method from their FinalConstruct() implementations.
b2a9ade0eaa3c7b26c02cc05f83c352cafb9e03avboxsync // get creation timestamp
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync// protected initializer/uninitializer for internal purposes only
b2a9ade0eaa3c7b26c02cc05f83c352cafb9e03avboxsync////////////////////////////////////////////////////////////////////////////////
b2a9ade0eaa3c7b26c02cc05f83c352cafb9e03avboxsync * Initializes the progress base object.
b2a9ade0eaa3c7b26c02cc05f83c352cafb9e03avboxsync * Subclasses should call this or any other #protectedInit() method from their
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * init() implementations.
b2a9ade0eaa3c7b26c02cc05f83c352cafb9e03avboxsync * @param aAutoInitSpan AutoInitSpan object instantiated by a subclass.
b2a9ade0eaa3c7b26c02cc05f83c352cafb9e03avboxsync * @param aParent Parent object (only for server-side Progress objects).
b2a9ade0eaa3c7b26c02cc05f83c352cafb9e03avboxsync * @param aInitiator Initiator of the task (for server-side objects. Can be
22ea904a6fe5c95f54c4374502747cc844ce8204vboxsync * NULL which means initiator = parent, otherwise must not
22ea904a6fe5c95f54c4374502747cc844ce8204vboxsync * be NULL).
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * @param aDescription ask description.
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * @param aID Address of result GUID structure (optional).
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * @return COM result indicator.
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsyncHRESULT ProgressBase::protectedInit (AutoInitSpan &aAutoInitSpan,
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync /* Guarantees subclasses call this method at the proper time */
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync AssertReturn(autoCaller.state() == InInit, E_FAIL);
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync /* share parent weakly */
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync /* assign (and therefore addref) initiator only if it is not VirtualBox
6b9316bfe743cc7d2ee00d925f4ab455bc224e86vboxsync * (to avoid cycling); otherwise mInitiator will remain null which means
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync * that it is the same as the parent */
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync /* add to the global collection of progress operations (note: after
fbf482cad760a830bc8789ad639162019954ba80vboxsync * creating mId) */
fbf482cad760a830bc8789ad639162019954ba80vboxsync * Initializes the progress base object.
fbf482cad760a830bc8789ad639162019954ba80vboxsync * This is a special initializer that doesn't initialize any field. Used by one
fbf482cad760a830bc8789ad639162019954ba80vboxsync * of the Progress::init() forms to create sub-progress operations combined
9ff5b937cfc7a0832f0d8f52ab642193c2a0670avboxsync * together using a CombinedProgress instance, so it doesn't require the parent,
fbf482cad760a830bc8789ad639162019954ba80vboxsync * initiator, description and doesn't create an ID.
fbf482cad760a830bc8789ad639162019954ba80vboxsync * Subclasses should call this or any other #protectedInit() method from their
fbf482cad760a830bc8789ad639162019954ba80vboxsync * init() implementations.
382dd16193dd5770e53a99d3e3f3bc4e96f1ddd8vboxsync * @param aAutoInitSpan AutoInitSpan object instantiated by a subclass.
fbf482cad760a830bc8789ad639162019954ba80vboxsyncHRESULT ProgressBase::protectedInit (AutoInitSpan &aAutoInitSpan)
fbf482cad760a830bc8789ad639162019954ba80vboxsync /* Guarantees subclasses call this method at the proper time */
fbf482cad760a830bc8789ad639162019954ba80vboxsync * Uninitializes the instance.
fbf482cad760a830bc8789ad639162019954ba80vboxsync * Subclasses should call this from their uninit() implementations.
fbf482cad760a830bc8789ad639162019954ba80vboxsync * @param aAutoUninitSpan AutoUninitSpan object instantiated by a subclass.
fbf482cad760a830bc8789ad639162019954ba80vboxsync * @note Using the mParent member after this method returns is forbidden.
fbf482cad760a830bc8789ad639162019954ba80vboxsyncvoid ProgressBase::protectedUninit (AutoUninitSpan &aAutoUninitSpan)
fbf482cad760a830bc8789ad639162019954ba80vboxsync /* release initiator (effective only if mInitiator has been assigned in
fbf482cad760a830bc8789ad639162019954ba80vboxsync * init()) */
fbf482cad760a830bc8789ad639162019954ba80vboxsync /* remove the added progress on failure to complete the initialization */
fbf482cad760a830bc8789ad639162019954ba80vboxsync if (aAutoUninitSpan.initFailed() && !mId.isEmpty())
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync// IProgress properties
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsync/////////////////////////////////////////////////////////////////////////////
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsyncSTDMETHODIMP ProgressBase::COMGETTER(Id) (BSTR *aId)
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
f7c0f913c4c22ee18059ff97055442566d0f14a1vboxsync /* mId is constant during life time, no need to lock */
0c9573129c50b7f9f4ea54e61417c2ed06bb8ebavboxsyncSTDMETHODIMP ProgressBase::COMGETTER(Description) (BSTR *aDescription)
d5bf937d132098565e18a0d1fc408fb777c5e5b6vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
3455d9b135d41903504b9be3f4eeaa038f6ee03avboxsync /* mDescription is constant during life time, no need to lock */
8a99522dee886d4ed00c8cd18788e9e722febd71vboxsyncSTDMETHODIMP ProgressBase::COMGETTER(Initiator) (IUnknown **aInitiator)
454ac5c6ef4960887035ceea6b5247789d3272davboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
454ac5c6ef4960887035ceea6b5247789d3272davboxsync /* mInitiator/mParent are constant during life time, no need to lock */
return S_OK;
return S_OK;
if (m_ulTotalOperationsWeight == 0)
double dPercent = ( (double)m_ulOperationsCompletedWeight // weight of operations that have been completed
+ ((double)m_ulOperationPercent * (double)m_ulCurrentOperationWeight / (double)100) // plus partial weight of the current operation
return dPercent;
if ( m_cMsTimeout
&& mCancelable
&& !mCanceled
Cancel();
if (mCompleted)
*aTimeRemaining = 0;
// Log(("ProgressBase::GetTimeRemaining: dPercentDone %RI32, ullTimeNow = %RI64, ullTimeElapsed = %RI64, ullTimeTotal = %RI64, ullTimeRemaining = %RI64\n",
return S_OK;
// do not report 100% until we're really really done with everything as the Qt GUI dismisses progress dialogs in that case
return S_OK;
return S_OK;
return S_OK;
if (!mCompleted)
return S_OK;
if (!mCompleted)
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
if (!mCancelable)
return S_OK;
return S_OK;
return resultCode;
return resultCode;
if (mCanceled)
mWaitersCount = 0;
return S_OK;
uninit();
// public initializer/uninitializer for internal purposes only
* in ProgressImpl.h as well).
* @param ulTotalOperationsWeight Total weight of operations; must be the sum of ulFirstOperationWeight and
#if !defined (VBOX_COM_INPROC)
LogFlowThisFunc(("aDescription=\"%ls\", cOperations=%d, ulTotalOperationsWeight=%d, bstrFirstOperationDescription=\"%ls\", ulFirstOperationWeight=%d\n",
#if !defined (VBOX_COM_INPROC)
m_ulCurrentOperation = 0;
m_ulOperationPercent = 0;
return rc;
m_ulCurrentOperation = 0;
m_ulOperationPercent = 0;
return rc;
if (mWaitersCount > 0)
if (!mCompleted)
if (mWaitersCount == 0)
if (!fForever)
vrc);
return S_OK;
if ( !mCompleted
mWaitersCount ++;
if (mWaitersCount == 0)
if (!fForever)
vrc);
return S_OK;
if (!mCancelable)
if (!mCanceled)
if (m_pfnCancelCallback)
return S_OK;
return E_FAIL;
return S_OK;
STDMETHODIMP Progress::SetNextOperation(IN_BSTR bstrNextOperationDescription, ULONG ulNextOperationsWeight)
if (mCanceled)
return E_FAIL;
m_ulOperationPercent = 0;
Log(("Progress::setNextOperation(%ls): ulNextOperationsWeight = %d; m_ulCurrentOperation is now %d, m_ulOperationsCompletedWeight is now %d\n",
m_bstrOperationDescription.raw(), ulNextOperationsWeight, m_ulCurrentOperation, m_ulOperationsCompletedWeight));
if (mWaitersCount > 0)
return S_OK;
#if !defined (VBOX_WITH_XPCOM)
return rc;
#if !defined VBOX_COM_INPROC
if (mParent)
if (mWaitersCount > 0)
return rc;
const char *aText,
return hrc;
const char *aText,
#if !defined VBOX_COM_INPROC
if (mParent)
if (mWaitersCount > 0)
return rc;
if (mCanceled)
mProgress = 0;
mCompletedOperations = 0;
return S_OK;
uninit();
// public initializer/uninitializer for internal purposes only
#if !defined (VBOX_COM_INPROC)
#if !defined (VBOX_COM_INPROC)
mCompletedOperations = 0;
m_ulCurrentOperation = 0;
if (mCancelable)
if (!cancelable)
return rc;
#if !defined (VBOX_COM_INPROC)
#if !defined (VBOX_COM_INPROC)
aId);
return rc;
mProgress = 0;
return S_OK;
AssertFailed();
return E_NOTIMPL;
AssertFailed();
return E_NOTIMPL;
if (!mCompleted)
if (!forever)
return S_OK;
return rc;
progress ++;
if (!forever)
return S_OK;
if (!mCancelable)
if (!mCanceled)
if (m_pfnCancelCallback)
return S_OK;
if (mCompleted)
return S_OK;
return rc;
if (fCompleted)
return rc;
return rc;
return rc;
return rc;
mProgress ++;
return rc;