ProgressImpl.cpp revision c7406a0a49c0faf05ed735c67c128fd09a0360b0
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VirtualBox Progress COM class implementation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
c97989161fbe75bc14cea477a5443bbf474dd3advboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (C) 2006-2013 Oracle Corporation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/types.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if defined(VBOX_WITH_XPCOM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <nsIServiceManager.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <nsIExceptionService.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <nsCOMPtr.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* defined(VBOX_WITH_XPCOM) */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "ProgressImpl.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_COM_INPROC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# include "VirtualBoxImpl.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "VirtualBoxErrorInfoImpl.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "Logging.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/time.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/semaphore.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/cpp/utils.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/err.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "AutoCaller.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncProgress::Progress()
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync#if !defined(VBOX_COM_INPROC)
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync : mParent(NULL)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncProgress::~Progress()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// IProgress properties
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getId(com::Guid &aId)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* mId is constant during life time, no need to lock */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aId = mId;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getDescription(com::Utf8Str &aDescription)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* mDescription is constant during life time, no need to lock */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aDescription = mDescription;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getInitiator(ComPtr<IUnknown> &aInitiator)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* mInitiator/mParent are constant during life time, no need to lock */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_COM_INPROC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mInitiator)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mInitiator.queryInterfaceTo(aInitiator.asOutParam());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComObjPtr<VirtualBox> pVirtualBox(mParent);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pVirtualBox.queryInterfaceTo(aInitiator.asOutParam());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mInitiator.queryInterfaceTo(aInitiator.asOutParam());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getCancelable(BOOL *aCancelable)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aCancelable = mCancelable;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Internal helper to compute the total percent value based on the member values and
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * returns it as a "double". This is used both by GetPercent (which returns it as a
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * rounded ULONG) and GetTimeRemaining().
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Requires locking by the caller!
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return fractional percentage as a double value.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncdouble Progress::i_calcTotalPercent()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // avoid division by zero
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (m_ulTotalOperationsWeight == 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync double dPercent = ( (double)m_ulOperationsCompletedWeight // weight of operations that have been completed
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync + ((double)m_ulOperationPercent *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (double)m_ulCurrentOperationWeight / (double)100) // plus partial weight of the current operation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ) * (double)100 / (double)m_ulTotalOperationsWeight;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return dPercent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Internal helper for automatically timing out the operation.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The caller should hold the object write lock.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid Progress::i_checkForAutomaticTimeout(void)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( m_cMsTimeout
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && mCancelable
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && !mCanceled
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && RTTimeMilliTS() - m_ullTimestamp > m_cMsTimeout
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Cancel();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getTimeRemaining(LONG *aTimeRemaining)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mCompleted)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aTimeRemaining = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync double dPercentDone = i_calcTotalPercent();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (dPercentDone < 1)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aTimeRemaining = -1; // unreliable, or avoid division by 0 below
cfb3a8ae5e9668de4506cf5c053b8009bcc89dafvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t ullTimeNow = RTTimeMilliTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t ullTimeElapsed = ullTimeNow - m_ullTimestamp;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t ullTimeTotal = (uint64_t)(ullTimeElapsed * 100 / dPercentDone);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t ullTimeRemaining = ullTimeTotal - ullTimeElapsed;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync// Log(("Progress::GetTimeRemaining: dPercentDone %RI32, ullTimeNow = %RI64, ullTimeElapsed = %RI64, ullTimeTotal = %RI64, ullTimeRemaining = %RI64\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// (uint32_t)dPercentDone, ullTimeNow, ullTimeElapsed, ullTimeTotal, ullTimeRemaining));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync *aTimeRemaining = (LONG)(ullTimeRemaining / 1000);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getPercent(ULONG *aPercent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync i_checkForAutomaticTimeout();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* checkForAutomaticTimeout requires a write lock. */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mCompleted && SUCCEEDED(mResultCode))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aPercent = 100;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync ULONG ulPercent = (ULONG)i_calcTotalPercent();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // do not report 100% until we're really really done with everything as the Qt GUI dismisses progress dialogs in that case
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( ulPercent == 100
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync && ( m_ulOperationPercent < 100
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || (m_ulCurrentOperation < m_cOperations -1)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aPercent = 99;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync *aPercent = ulPercent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync i_checkForAutomaticTimeout();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getCompleted(BOOL *aCompleted)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aCompleted = mCompleted;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getCanceled(BOOL *aCanceled)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync *aCanceled = mCanceled;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getResultCode(LONG *aResultCode)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!mCompleted)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_FAIL,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Result code is not available, operation is still in progress"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aResultCode = mResultCode;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getErrorInfo(ComPtr<IVirtualBoxErrorInfo> &aErrorInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!mCompleted)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_FAIL,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Error info is not available, operation is still in progress"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mErrorInfo.queryInterfaceTo(aErrorInfo.asOutParam());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getOperationCount(ULONG *aOperationCount)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aOperationCount = m_cOperations;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getOperation(ULONG *aOperation)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aOperation = m_ulCurrentOperation;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getOperationDescription(com::Utf8Str &aOperationDescription)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aOperationDescription = m_operationDescription;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getOperationPercent(ULONG *aOperationPercent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mCompleted && SUCCEEDED(mResultCode))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aOperationPercent = 100;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aOperationPercent = m_ulOperationPercent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getOperationWeight(ULONG *aOperationWeight)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aOperationWeight = m_ulCurrentOperationWeight;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::setTimeout(ULONG aTimeout)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!mCancelable)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(VBOX_E_INVALID_OBJECT_STATE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Operation cannot be canceled"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogThisFunc(("%#x => %#x\n", m_cMsTimeout, aTimeout));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_cMsTimeout = aTimeout;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::getTimeout(ULONG *aTimeout)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aTimeout = m_cMsTimeout;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// public methods only for internal purposes
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync////////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Sets the cancelation callback, checking for cancelation first.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns Success indicator.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @retval true on success.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @retval false if the progress object has already been canceled or is in an
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * invalid state
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pfnCallback The function to be called upon cancelation.
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync * @param pvUser The callback argument.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncbool Progress::i_setCancelCallback(void (*pfnCallback)(void *), void *pvUser)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertComRCReturn(autoCaller.rc(), false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync i_checkForAutomaticTimeout();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mCanceled)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_pvCancelUserArg = pvUser;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_pfnCancelCallback = pfnCallback;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::FinalConstruct()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCancelable = FALSE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCompleted = FALSE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCanceled = FALSE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mResultCode = S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_cOperations
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync = m_ulTotalOperationsWeight
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync = m_ulOperationsCompletedWeight
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync = m_ulCurrentOperation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync = m_ulCurrentOperationWeight
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync = m_ulOperationPercent
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync = m_cMsTimeout
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // get creation timestamp
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ullTimestamp = RTTimeMilliTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_pfnCancelCallback = NULL;
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync m_pvCancelUserArg = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = Progress::BaseFinalConstruct();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCompletedSem = NIL_RTSEMEVENTMULTI;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mWaitersCount = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid Progress::FinalRelease()
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync uninit();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync BaseFinalRelease();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// public initializer/uninitializer for internal purposes only
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync////////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Initializes the normal progress object. With this variant, one can have
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * an arbitrary number of sub-operation which IProgress can analyze to
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * have a weighted progress computed.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * For example, say that one IProgress is supposed to track the cloning
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * of two hard disk images, which are 100 MB and 1000 MB in size, respectively,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * and each of these hard disks should be one sub-operation of the IProgress.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Obviously the progress would be misleading if the progress displayed 50%
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * after the smaller image was cloned and would then take much longer for
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the second half.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * With weighted progress, one can invoke the following calls:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * 1) create progress object with cOperations = 2 and ulTotalOperationsWeight =
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * 1100 (100 MB plus 1100, but really the weights can be any ULONG); pass
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * in ulFirstOperationWeight = 100 for the first sub-operation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * 2) Then keep calling setCurrentOperationProgress() with a percentage
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * for the first image; the total progress will increase up to a value
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * of 9% (100MB / 1100MB * 100%).
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * 3) Then call setNextOperation with the second weight (1000 for the megabytes
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * of the second disk).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * 4) Then keep calling setCurrentOperationProgress() with a percentage for
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * the second image, where 100% of the operation will then yield a 100%
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * progress of the entire task.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Weighting is optional; you can simply assign a weight of 1 to each operation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * and pass ulTotalOperationsWeight == cOperations to this constructor (but
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * for that variant and for backwards-compatibility a simpler constructor exists
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * in ProgressImpl.h as well).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Even simpler, if you need no sub-operations at all, pass in cOperations =
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ulTotalOperationsWeight = ulFirstOperationWeight = 1.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aParent See Progress::init().
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aInitiator See Progress::init().
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aDescription See Progress::init().
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aCancelable Flag whether the task maybe canceled.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param cOperations Number of operations within this task (at least 1).
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync * @param ulTotalOperationsWeight Total weight of operations; must be the sum of ulFirstOperationWeight and
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * what is later passed with each subsequent setNextOperation() call.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param bstrFirstOperationDescription Description of the first operation.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ulFirstOperationWeight Weight of first sub-operation.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aId See Progress::init().
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::init(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_COM_INPROC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VirtualBox *aParent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IUnknown *aInitiator,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Utf8Str aDescription,
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync BOOL aCancelable,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG cOperations,
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync ULONG ulTotalOperationsWeight,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Utf8Str aFirstOperationDescription,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG ulFirstOperationWeight,
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync OUT_GUID aId /* = NULL */)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogFlowThisFunc(("aDescription=\"%ls\", cOperations=%d, ulTotalOperationsWeight=%d, bstrFirstOperationDescription=\"%ls\", ulFirstOperationWeight=%d\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aDescription.c_str(),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cOperations,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ulTotalOperationsWeight,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aFirstOperationDescription.c_str(),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ulFirstOperationWeight));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(ulTotalOperationsWeight >= 1, E_INVALIDARG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Enclose the state transition NotReady->InInit->Ready */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoInitSpan autoInitSpan(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d8df004f4caf4f71e78f0be1cc2e2a918358ae9fvboxsync HRESULT rc = S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// rc = Progress::init(
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//#if !defined(VBOX_COM_INPROC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// aParent,
344f8996b5cf3f8bbc2c361f9d526eb5b1350916vboxsync//#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// aInitiator, aDescription, FALSE, aId);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// NA
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_COM_INPROC)
d8df004f4caf4f71e78f0be1cc2e2a918358ae9fvboxsync AssertReturn(aParent, E_INVALIDARG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(aInitiator, E_INVALIDARG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
344f8996b5cf3f8bbc2c361f9d526eb5b1350916vboxsync#if !defined(VBOX_COM_INPROC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* share parent weakly */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(mParent) = aParent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_COM_INPROC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* assign (and therefore addref) initiator only if it is not VirtualBox
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * * (to avoid cycling); otherwise mInitiator will remain null which means
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * * that it is the same as the parent */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aInitiator)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComObjPtr<VirtualBox> pVirtualBox(mParent);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!(pVirtualBox == aInitiator))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(mInitiator) = aInitiator;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(mInitiator) = aInitiator;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(mId).create();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aId)
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync mId.cloneTo(aId);
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_COM_INPROC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* add to the global collection of progress operations (note: after
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * * creating mId) */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mParent->i_addProgress(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(mDescription) = aDescription;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// end of assertion
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCancelable = aCancelable;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_cOperations = cOperations;
571525c203930230b3ae9badba7c2d2d12f21d05vboxsync m_ulTotalOperationsWeight = ulTotalOperationsWeight;
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync m_ulOperationsCompletedWeight = 0;
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync m_ulCurrentOperation = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_operationDescription = aFirstOperationDescription;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulCurrentOperationWeight = ulFirstOperationWeight;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulOperationPercent = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int vrc = RTSemEventMultiCreate(&mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComAssertRCRet(vrc, E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemEventMultiReset(mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Confirm a successful initialization when it's the case */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (SUCCEEDED(rc))
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync autoInitSpan.setSucceeded();
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Initializes the sub-progress object that represents a specific operation of
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the whole task.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Objects initialized with this method are then combined together into the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * single task using a Progress instance, so it doesn't require the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * parent, initiator, description and doesn't create an ID. Note that calling
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * respective getter methods on an object initialized with this method is
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * useless. Such objects are used only to provide a separate wait semaphore and
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * store individual operation descriptions.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aCancelable Flag whether the task maybe canceled.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aOperationCount Number of sub-operations within this task (at least 1).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aOperationDescription Description of the individual operation.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::init(BOOL aCancelable,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG aOperationCount,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Utf8Str aOperationDescription)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFunc(("aOperationDescription=\"%s\"\n", aOperationDescription.c_str()));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Enclose the state transition NotReady->InInit->Ready */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoInitSpan autoInitSpan(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Guarantees subclasses call this method at the proper time */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NOREF(autoInitSpan);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCancelable = aCancelable;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // for this variant we assume for now that all operations are weighed "1"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // and equal total weight = operation count
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_cOperations = aOperationCount;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulTotalOperationsWeight = aOperationCount;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulOperationsCompletedWeight = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulCurrentOperation = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_operationDescription = aOperationDescription;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulCurrentOperationWeight = 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulOperationPercent = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int vrc = RTSemEventMultiCreate(&mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComAssertRCRet(vrc, E_FAIL);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemEventMultiReset(mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync /* Confirm a successful initialization when it's the case */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (SUCCEEDED(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync autoInitSpan.setSucceeded();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Uninitializes the instance and sets the ready flag to FALSE.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid Progress::uninit()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFunc(("\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Enclose the state transition Ready->InUninit->NotReady */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoUninitSpan autoUninitSpan(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (autoUninitSpan.uninitDone())
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* wake up all threads still waiting on occasion */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mWaitersCount > 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("WARNING: There are still %d threads waiting for '%s' completion!\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mWaitersCount, mDescription.c_str()));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemEventMultiSignal(mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemEventMultiDestroy(mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* release initiator (effective only if mInitiator has been assigned in
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * * init()) */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(mInitiator).setNull();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_COM_INPROC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mParent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* remove the added progress on failure to complete the initialization */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (autoUninitSpan.initFailed() && mId.isValid() && !mId.isZero())
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mParent->i_removeProgress(mId.ref());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(mParent) = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// IProgress properties
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// IProgress methods
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @note XPCOM: when this method is not called on the main XPCOM thread, it
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * simply blocks the thread until mCompletedSem is signalled. If the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * thread has its own event queue (hmm, what for?) that it must run, then
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * calling this method will definitely freeze event processing.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::waitForCompletion(LONG aTimeout)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFuncEnter();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFunc(("aTimeout=%d\n", aTimeout));
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync /* if we're already completed, take a shortcut */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!mCompleted)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int vrc = VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool fForever = aTimeout < 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int64_t timeLeft = aTimeout;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int64_t lastTime = RTTimeMilliTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (!mCompleted && (fForever || timeLeft > 0))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mWaitersCount++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync alock.release();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vrc = RTSemEventMultiWait(mCompletedSem,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fForever ? RT_INDEFINITE_WAIT : (RTMSINTERVAL)timeLeft);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync alock.acquire();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mWaitersCount--;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the last waiter resets the semaphore */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mWaitersCount == 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemEventMultiReset(mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (RT_FAILURE(vrc) && vrc != VERR_TIMEOUT)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!fForever)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int64_t now = RTTimeMilliTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync timeLeft -= now - lastTime;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync lastTime = now;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_FAILURE(vrc) && vrc != VERR_TIMEOUT)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(VBOX_E_IPRT_ERROR,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Failed to wait for the task completion (%Rrc)"),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vrc);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFuncLeave();
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @note XPCOM: when this method is not called on the main XPCOM thread, it
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * simply blocks the thread until mCompletedSem is signalled. If the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * thread has its own event queue (hmm, what for?) that it must run, then
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * calling this method will definitely freeze event processing.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::waitForOperationCompletion(ULONG aOperation, LONG aTimeout)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFuncEnter();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFunc(("aOperation=%d, aTimeout=%d\n", aOperation, aTimeout));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CheckComArgExpr(aOperation, aOperation < m_cOperations);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* if we're already completed or if the given operation is already done,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * then take a shortcut */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( !mCompleted
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && aOperation >= m_ulCurrentOperation)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int vrc = VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool fForever = aTimeout < 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int64_t timeLeft = aTimeout;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync int64_t lastTime = RTTimeMilliTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while ( !mCompleted && aOperation >= m_ulCurrentOperation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && (fForever || timeLeft > 0))
430b3ee9393ac51b1e3670019fe3ece0a4d59f81vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mWaitersCount ++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync alock.release();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vrc = RTSemEventMultiWait(mCompletedSem,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fForever ? RT_INDEFINITE_WAIT : (unsigned) timeLeft);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync alock.acquire();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mWaitersCount--;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the last waiter resets the semaphore */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mWaitersCount == 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemEventMultiReset(mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_FAILURE(vrc) && vrc != VERR_TIMEOUT)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!fForever)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int64_t now = RTTimeMilliTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync timeLeft -= now - lastTime;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync lastTime = now;
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_FAILURE(vrc) && vrc != VERR_TIMEOUT)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_FAIL,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Failed to wait for the operation completion (%Rrc)"),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vrc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFuncLeave();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::waitForAsyncProgressCompletion(const ComPtr<IProgress> &aPProgressAsync)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFuncEnter();
571525c203930230b3ae9badba7c2d2d12f21d05vboxsync
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync /* Note: we don't lock here, cause we just using public methods. */
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync BOOL fCancelable = FALSE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync BOOL fCompleted = FALSE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync BOOL fCanceled = FALSE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG prevPercent = UINT32_MAX;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG currentPercent = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG cOp = 0;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync /* Is the async process cancelable? */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync rc = aPProgressAsync->COMGETTER(Cancelable)(&fCancelable);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Loop as long as the sync process isn't completed. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (SUCCEEDED(aPProgressAsync->COMGETTER(Completed(&fCompleted))))
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync /* We can forward any cancel request to the async process only when
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * it is cancelable. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (fCancelable)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = COMGETTER(Canceled)(&fCanceled);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (fCanceled)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = aPProgressAsync->Cancel();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Even if the user canceled the process, we have to wait until the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync async task has finished his work (cleanup and such). Otherwise there
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync will be sync trouble (still wrong state, dead locks, ...) on the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync used objects. So just do nothing, but wait for the complete
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync notification. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!fCanceled)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Check if the current operation has changed. It is also possible that
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * in the meantime more than one async operation was finished. So we
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * have to loop as long as we reached the same operation count. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG curOp;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (;;)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = aPProgressAsync->COMGETTER(Operation(&curOp));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (cOp != curOp)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Bstr bstr;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG currentWeight;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = aPProgressAsync->COMGETTER(OperationDescription(bstr.asOutParam()));
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = aPProgressAsync->COMGETTER(OperationWeight(&currentWeight));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = SetNextOperation(bstr.raw(), currentWeight);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ++cOp;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = aPProgressAsync->COMGETTER(OperationPercent(&currentPercent));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (currentPercent != prevPercent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync prevPercent = currentPercent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = SetCurrentOperationProgress(currentPercent);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (fCompleted)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Make sure the loop is not too tight */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = aPProgressAsync->WaitForCompletion(100);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFuncLeave();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::cancel()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!mCancelable)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync return setError(VBOX_E_INVALID_OBJECT_STATE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Operation cannot be canceled"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!mCanceled)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogThisFunc(("Canceling\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCanceled = TRUE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (m_pfnCancelCallback)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_pfnCancelCallback(m_pvCancelUserArg);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogThisFunc(("Already canceled\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Updates the percentage value of the current operation.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aPercent New percentage value of the operation in progress
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * (in range [0, 100]).
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::setCurrentOperationProgress(ULONG aPercent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgReturn(aPercent <= 100, ("%u\n", aPercent), E_INVALIDARG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync i_checkForAutomaticTimeout();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mCancelable && mCanceled)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(!mCompleted);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return E_FAIL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(!mCompleted && !mCanceled, E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulOperationPercent = aPercent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync return S_OK;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Signals that the current operation is successfully completed and advances to
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the next operation. The operation percentage is reset to 0.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * @param aOperationDescription Description of the next operation.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @note The current operation must not be the last one.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::setNextOperation(const com::Utf8Str &aNextOperationDescription, ULONG aNextOperationsWeight)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mCanceled)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync return E_FAIL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(!mCompleted, E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(m_ulCurrentOperation + 1 < m_cOperations, E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ++m_ulCurrentOperation;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulOperationsCompletedWeight += m_ulCurrentOperationWeight;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_operationDescription = aNextOperationDescription;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulCurrentOperationWeight = aNextOperationsWeight;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulOperationPercent = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("Progress::setNextOperation(%s): aNextOperationsWeight = %d; m_ulCurrentOperation is now %d, m_ulOperationsCompletedWeight is now %d\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_operationDescription.c_str(), aNextOperationsWeight, m_ulCurrentOperation, m_ulOperationsCompletedWeight));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* wake up all waiting threads */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mWaitersCount > 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemEventMultiSignal(mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync// public methods only for internal purposes
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Sets the internal result code and attempts to retrieve additional error
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * info from the current thread. Gets called from Progress::notifyComplete(),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * but can be called again to override a previous result set with
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * notifyComplete().
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aResultCode
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsyncHRESULT Progress::i_setResultCode(HRESULT aResultCode)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync mResultCode = aResultCode;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync HRESULT rc = S_OK;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(aResultCode))
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* try to import error info from the current thread */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined(VBOX_WITH_XPCOM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComPtr<IErrorInfo> err;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ::GetErrorInfo(0, err.asOutParam());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (rc == S_OK && err)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = err.queryInterfaceTo(mErrorInfo.asOutParam());
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (SUCCEEDED(rc) && !mErrorInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = E_FAIL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else /* !defined(VBOX_WITH_XPCOM) */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync nsCOMPtr<nsIExceptionService> es;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (NS_SUCCEEDED(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync nsCOMPtr <nsIExceptionManager> em;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = es->GetCurrentExceptionManager(getter_AddRefs(em));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (NS_SUCCEEDED(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComPtr<nsIException> ex;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = em->GetCurrentException(ex.asOutParam());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (NS_SUCCEEDED(rc) && ex)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = ex.queryInterfaceTo(mErrorInfo.asOutParam());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (NS_SUCCEEDED(rc) && !mErrorInfo)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = E_FAIL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* !defined(VBOX_WITH_XPCOM) */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsg(rc == S_OK, ("Couldn't get error info (rc=%08X) while trying to set a failed result (%08X)!\n",
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync rc, aResultCode));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Marks the whole task as complete and sets the result code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * If the result code indicates a failure (|FAILED(@a aResultCode)|) then this
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * method will import the error info from the current thread and assign it to
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * the errorInfo attribute (it will return an error if no info is available in
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * such case).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * If the result code indicates a success (|SUCCEEDED(@a aResultCode)|) then
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the current operation is set to the last.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Note that this method may be called only once for the given Progress object.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Subsequent calls will assert.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * @param aResultCode Operation result code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::i_notifyComplete(HRESULT aResultCode)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AssertComRCReturnRC(autoCaller.rc());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(mCompleted == FALSE, E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFunc(("aResultCode=%d\n", aResultCode));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mCanceled && SUCCEEDED(aResultCode))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aResultCode = E_FAIL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = i_setResultCode(aResultCode);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync mCompleted = TRUE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!FAILED(aResultCode))
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulCurrentOperation = m_cOperations - 1; /* last operation */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_ulOperationPercent = 100;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined VBOX_COM_INPROC
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* remove from the global collection of pending progress operations */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mParent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mParent->i_removeProgress(mId.ref());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* wake up all waiting threads */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mWaitersCount > 0)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync RTSemEventMultiSignal(mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Wrapper around Progress:notifyCompleteV.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::i_notifyComplete(HRESULT aResultCode,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const GUID &aIID,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char *pcszComponent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char *aText,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ...)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync va_list va;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync va_start(va, aText);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT hrc = i_notifyCompleteV(aResultCode, aIID, pcszComponent, aText, va);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync va_end(va);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return hrc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Marks the operation as complete and attaches full error info.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync * See VirtualBoxBase::setError(HRESULT, const GUID &, const wchar_t
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * *, const char *, ...) for more info.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aResultCode Operation result (error) code, must not be S_OK.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aIID IID of the interface that defines the error.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aComponent Name of the component that generates the error.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * @param aText Error message (must not be null), an RTStrPrintf-like
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * format string in UTF-8 encoding.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param va List of arguments for the format string.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT Progress::i_notifyCompleteV(HRESULT aResultCode,
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync const GUID &aIID,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char *pcszComponent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char *aText,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync va_list va)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Utf8Str text(aText, va);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AssertComRCReturnRC(autoCaller.rc());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AssertReturn(mCompleted == FALSE, E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mCanceled && SUCCEEDED(aResultCode))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aResultCode = E_FAIL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCompleted = TRUE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mResultCode = aResultCode;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(FAILED(aResultCode), E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComObjPtr<VirtualBoxErrorInfo> errorInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = errorInfo.createObject();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertComRC(rc);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (SUCCEEDED(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync errorInfo->init(aResultCode, aIID, pcszComponent, text);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync errorInfo.queryInterfaceTo(mErrorInfo.asOutParam());
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if !defined VBOX_COM_INPROC
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* remove from the global collection of pending progress operations */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mParent)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mParent->i_removeProgress(mId.ref());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* wake up all waiting threads */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mWaitersCount > 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTSemEventMultiSignal(mCompletedSem);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Notify the progress object that we're almost at the point of no return.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This atomically checks for and disables cancelation. Calls to
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * IProgress::Cancel() made after a successful call to this method will fail
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * and the user can be told. While this isn't entirely clean behavior, it
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync * prevents issues with an irreversible actually operation succeeding while the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * user believe it was rolled back.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns Success indicator.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @retval true on success.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * @retval false if the progress object has already been canceled or is in an
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * invalid state
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncbool Progress::i_notifyPointOfNoReturn(void)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertComRCReturn(autoCaller.rc(), false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (mCanceled)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogThisFunc(("returns false\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return false;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCancelable = FALSE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogThisFunc(("returns true\n"));
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync return true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync