VirtualBox

source: vbox/trunk/src/VBox/Main/include/ProgressImpl.h@ 17895

Last change on this file since 17895 was 17684, checked in by vboxsync, 16 years ago

#3551: “Main: Replace remaining collections with safe arrays”
Replaced HostUSBDeviceCollection. Reviewed/Okayed by dmik, sunlover.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1/* $Id: ProgressImpl.h 17684 2009-03-11 12:15:33Z vboxsync $ */
2/** @file
3 *
4 * VirtualBox COM class implementation
5 */
6
7/*
8 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#ifndef ____H_PROGRESSIMPL
24#define ____H_PROGRESSIMPL
25
26#include "VirtualBoxBase.h"
27
28#include <VBox/com/SupportErrorInfo.h>
29
30#include <iprt/semaphore.h>
31
32#include <vector>
33
34class VirtualBox;
35
36////////////////////////////////////////////////////////////////////////////////
37
38/**
39 * Base component class for progress objects.
40 */
41class ATL_NO_VTABLE ProgressBase :
42 public VirtualBoxBaseNEXT,
43 public com::SupportErrorInfoBase,
44 public VirtualBoxSupportTranslation <ProgressBase>,
45 public IProgress
46{
47protected:
48
49 VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (ProgressBase)
50
51 DECLARE_EMPTY_CTOR_DTOR (ProgressBase)
52
53 HRESULT FinalConstruct();
54
55 // protected initializer/uninitializer for internal purposes only
56 HRESULT protectedInit (AutoInitSpan &aAutoInitSpan,
57#if !defined (VBOX_COM_INPROC)
58 VirtualBox *aParent,
59#endif
60 IUnknown *aInitiator,
61 CBSTR aDescription, OUT_GUID aId = NULL);
62 HRESULT protectedInit (AutoInitSpan &aAutoInitSpan);
63 void protectedUninit (AutoUninitSpan &aAutoUninitSpan);
64
65public:
66
67 // IProgress properties
68 STDMETHOD(COMGETTER(Id)) (OUT_GUID aId);
69 STDMETHOD(COMGETTER(Description)) (BSTR *aDescription);
70 STDMETHOD(COMGETTER(Initiator)) (IUnknown **aInitiator);
71
72 // IProgress properties
73 STDMETHOD(COMGETTER(Cancelable)) (BOOL *aCancelable);
74 STDMETHOD(COMGETTER(Percent)) (LONG *aPercent);
75 STDMETHOD(COMGETTER(Completed)) (BOOL *aCompleted);
76 STDMETHOD(COMGETTER(Canceled)) (BOOL *aCanceled);
77 STDMETHOD(COMGETTER(ResultCode)) (HRESULT *aResultCode);
78 STDMETHOD(COMGETTER(ErrorInfo)) (IVirtualBoxErrorInfo **aErrorInfo);
79 STDMETHOD(COMGETTER(OperationCount)) (ULONG *aOperationCount);
80 STDMETHOD(COMGETTER(Operation)) (ULONG *aCount);
81 STDMETHOD(COMGETTER(OperationDescription)) (BSTR *aOperationDescription);
82 STDMETHOD(COMGETTER(OperationPercent)) (LONG *aOperationPercent);
83
84 // public methods only for internal purposes
85
86 static HRESULT setErrorInfoOnThread (IProgress *aProgress);
87
88 // unsafe inline public methods for internal purposes only (ensure there is
89 // a caller and a read lock before calling them!)
90
91 BOOL completed() const { return mCompleted; }
92 HRESULT resultCode() const { return mResultCode; }
93
94protected:
95
96#if !defined (VBOX_COM_INPROC)
97 /** Weak parent. */
98 const ComObjPtr <VirtualBox, ComWeakRef> mParent;
99#endif
100
101 const ComPtr <IUnknown> mInitiator;
102
103 const Guid mId;
104 const Bstr mDescription;
105
106 /* The fields below are to be properly initalized by subclasses */
107
108 BOOL mCompleted;
109 BOOL mCancelable;
110 BOOL mCanceled;
111 HRESULT mResultCode;
112 ComPtr <IVirtualBoxErrorInfo> mErrorInfo;
113
114 ULONG mOperationCount;
115 ULONG mOperation;
116 Bstr mOperationDescription;
117 LONG mOperationPercent;
118};
119
120////////////////////////////////////////////////////////////////////////////////
121
122/**
123 * Normal progress object.
124 */
125class ATL_NO_VTABLE Progress :
126 public com::SupportErrorInfoDerived <ProgressBase, Progress, IProgress>,
127 public VirtualBoxSupportTranslation <Progress>
128{
129
130public:
131
132 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE (Progress)
133
134 DECLARE_NOT_AGGREGATABLE (Progress)
135
136 DECLARE_PROTECT_FINAL_CONSTRUCT()
137
138 BEGIN_COM_MAP (Progress)
139 COM_INTERFACE_ENTRY (ISupportErrorInfo)
140 COM_INTERFACE_ENTRY (IProgress)
141 END_COM_MAP()
142
143 NS_DECL_ISUPPORTS
144
145 HRESULT FinalConstruct();
146 void FinalRelease();
147
148 // public initializer/uninitializer for internal purposes only
149
150 HRESULT init (
151#if !defined (VBOX_COM_INPROC)
152 VirtualBox *aParent,
153#endif
154 IUnknown *aInitiator,
155 CBSTR aDescription, BOOL aCancelable,
156 OUT_GUID aId = NULL)
157 {
158 return init (
159#if !defined (VBOX_COM_INPROC)
160 aParent,
161#endif
162 aInitiator, aDescription, aCancelable, 1, aDescription, aId);
163 }
164
165 HRESULT init (
166#if !defined (VBOX_COM_INPROC)
167 VirtualBox *aParent,
168#endif
169 IUnknown *aInitiator,
170 CBSTR aDescription, BOOL aCancelable,
171 ULONG aOperationCount, CBSTR aOperationDescription,
172 OUT_GUID aId = NULL);
173
174 HRESULT init (BOOL aCancelable, ULONG aOperationCount,
175 CBSTR aOperationDescription);
176
177 void uninit();
178
179 // IProgress methods
180 STDMETHOD(WaitForCompletion) (LONG aTimeout);
181 STDMETHOD(WaitForOperationCompletion) (ULONG aOperation, LONG aTimeout);
182 STDMETHOD(Cancel)();
183
184 // public methods only for internal purposes
185
186 HRESULT notifyProgress (LONG aPercent);
187 HRESULT advanceOperation (CBSTR aOperationDescription);
188
189 HRESULT notifyComplete (HRESULT aResultCode);
190 HRESULT notifyComplete (HRESULT aResultCode, const GUID &aIID,
191 const Bstr &aComponent,
192 const char *aText, ...);
193 HRESULT notifyCompleteBstr (HRESULT aResultCode, const GUID &aIID,
194 const Bstr &aComponent, const Bstr &aText);
195
196 /** For com::SupportErrorInfoImpl. */
197 static const char *ComponentName() { return "Progress"; }
198
199private:
200
201 RTSEMEVENTMULTI mCompletedSem;
202 ULONG mWaitersCount;
203};
204
205////////////////////////////////////////////////////////////////////////////////
206
207/**
208 * The CombinedProgress class allows to combine several progress objects to a
209 * single progress component. This single progress component will treat all
210 * operations of individual progress objects as a single sequence of operations
211 * that follow each other in the same order as progress objects are passed to
212 * the #init() method.
213 *
214 * Individual progress objects are sequentially combined so that this progress
215 * object:
216 *
217 * - is cancelable only if all progresses are cancelable.
218 * - is canceled once a progress that follows next to successfully completed
219 * ones reports it was canceled.
220 * - is completed successfully only after all progresses are completed
221 * successfully.
222 * - is completed unsuccessfully once a progress that follows next to
223 * successfully completed ones reports it was completed unsuccessfully;
224 * the result code and error info of the unsuccessful progress
225 * will be reported as the result code and error info of this progress.
226 * - returns N as the operation number, where N equals to the number of
227 * operations in all successfully completed progresses starting from the
228 * first one plus the operation number of the next (not yet complete)
229 * progress; the operation description of the latter one is reported as
230 * the operation description of this progress object.
231 * - returns P as the percent value, where P equals to the sum of percents
232 * of all successfully completed progresses starting from the
233 * first one plus the percent value of the next (not yet complete)
234 * progress, normalized to 100%.
235 *
236 * @note It's the respoisibility of the combined progress object creator to
237 * complete individual progresses in the right order: if, let's say, the
238 * last progress is completed before all previous ones,
239 * #WaitForCompletion(-1) will most likely give 100% CPU load because it
240 * will be in a loop calling a method that returns immediately.
241 */
242class ATL_NO_VTABLE CombinedProgress :
243 public com::SupportErrorInfoDerived <ProgressBase, CombinedProgress, IProgress>,
244 public VirtualBoxSupportTranslation <CombinedProgress>
245{
246
247public:
248
249 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE (CombinedProgress)
250
251 DECLARE_NOT_AGGREGATABLE (CombinedProgress)
252
253 DECLARE_PROTECT_FINAL_CONSTRUCT()
254
255 BEGIN_COM_MAP (CombinedProgress)
256 COM_INTERFACE_ENTRY (ISupportErrorInfo)
257 COM_INTERFACE_ENTRY (IProgress)
258 END_COM_MAP()
259
260 NS_DECL_ISUPPORTS
261
262 HRESULT FinalConstruct();
263 void FinalRelease();
264
265 // public initializer/uninitializer for internal purposes only
266
267 HRESULT init (
268#if !defined (VBOX_COM_INPROC)
269 VirtualBox *aParent,
270#endif
271 IUnknown *aInitiator,
272 CBSTR aDescription,
273 IProgress *aProgress1, IProgress *aProgress2,
274 OUT_GUID aId = NULL);
275
276 /**
277 * Initializes the combined progress object given the first and the last
278 * normal progress object from the list.
279 *
280 * @param aParent See ProgressBase::init().
281 * @param aInitiator See ProgressBase::init().
282 * @param aDescription See ProgressBase::init().
283 * @param aFirstProgress Iterator of the first normal progress object.
284 * @param aSecondProgress Iterator of the last normal progress object.
285 * @param aId See ProgressBase::init().
286 */
287 template <typename InputIterator>
288 HRESULT init (
289#if !defined (VBOX_COM_INPROC)
290 VirtualBox *aParent,
291#endif
292 IUnknown *aInitiator,
293 CBSTR aDescription,
294 InputIterator aFirstProgress, InputIterator aLastProgress,
295 OUT_GUID aId = NULL)
296 {
297 /* Enclose the state transition NotReady->InInit->Ready */
298 AutoInitSpan autoInitSpan (this);
299 AssertReturn (autoInitSpan.isOk(), E_FAIL);
300
301 mProgresses = ProgressVector (aFirstProgress, aLastProgress);
302
303 HRESULT rc = protectedInit (autoInitSpan,
304#if !defined (VBOX_COM_INPROC)
305 aParent,
306#endif
307 aInitiator, aDescription, aId);
308
309 /* Confirm a successful initialization when it's the case */
310 if (SUCCEEDED (rc))
311 autoInitSpan.setSucceeded();
312
313 return rc;
314 }
315
316protected:
317
318 HRESULT protectedInit (AutoInitSpan &aAutoInitSpan,
319#if !defined (VBOX_COM_INPROC)
320 VirtualBox *aParent,
321#endif
322 IUnknown *aInitiator,
323 CBSTR aDescription, OUT_GUID aId);
324
325public:
326
327 void uninit();
328
329 // IProgress properties
330 STDMETHOD(COMGETTER(Percent)) (LONG *aPercent);
331 STDMETHOD(COMGETTER(Completed)) (BOOL *aCompleted);
332 STDMETHOD(COMGETTER(Canceled)) (BOOL *aCanceled);
333 STDMETHOD(COMGETTER(ResultCode)) (HRESULT *aResultCode);
334 STDMETHOD(COMGETTER(ErrorInfo)) (IVirtualBoxErrorInfo **aErrorInfo);
335 STDMETHOD(COMGETTER(Operation)) (ULONG *aCount);
336 STDMETHOD(COMGETTER(OperationDescription)) (BSTR *aOperationDescription);
337 STDMETHOD(COMGETTER(OperationPercent)) (LONG *aOperationPercent);
338
339 // IProgress methods
340 STDMETHOD(WaitForCompletion) (LONG aTimeout);
341 STDMETHOD(WaitForOperationCompletion) (ULONG aOperation, LONG aTimeout);
342 STDMETHOD(Cancel)();
343
344 // public methods only for internal purposes
345
346 /** For com::SupportErrorInfoImpl. */
347 static const char *ComponentName() { return "CombinedProgress"; }
348
349private:
350
351 HRESULT checkProgress();
352
353 typedef std::vector <ComPtr <IProgress> > ProgressVector;
354 ProgressVector mProgresses;
355
356 size_t mProgress;
357 ULONG mCompletedOperations;
358};
359
360#endif /* ____H_PROGRESSIMPL */
361/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette