VirtualBox

source: vbox/trunk/src/VBox/Main/include/VirtualBoxBase.h@ 21878

Last change on this file since 21878 was 21878, checked in by vboxsync, 15 years ago

Main: coding style: have Main obey the standard VirtualBox coding style rules (no functional changes)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 96.9 KB
Line 
1/** @file
2 *
3 * VirtualBox COM base classes definition
4 */
5
6/*
7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef ____H_VIRTUALBOXBASEIMPL
23#define ____H_VIRTUALBOXBASEIMPL
24
25#include <iprt/cdefs.h>
26#include <iprt/critsect.h>
27#include <iprt/thread.h>
28
29#include <list>
30#include <map>
31
32#include "VBox/com/ErrorInfo.h"
33
34#include "VBox/com/VirtualBox.h"
35
36// avoid including VBox/settings.h and VBox/xml.h;
37// only declare the classes
38namespace settings
39{
40class XmlTreeBackend;
41class TreeBackend;
42class Key;
43}
44
45namespace xml
46{
47class File;
48}
49
50#include "AutoLock.h"
51
52using namespace com;
53using namespace util;
54
55#if !defined (VBOX_WITH_XPCOM)
56
57#include <atlcom.h>
58
59/* use a special version of the singleton class factory,
60 * see KB811591 in msdn for more info. */
61
62#undef DECLARE_CLASSFACTORY_SINGLETON
63#define DECLARE_CLASSFACTORY_SINGLETON(obj) DECLARE_CLASSFACTORY_EX(CMyComClassFactorySingleton<obj>)
64
65template <class T>
66class CMyComClassFactorySingleton : public CComClassFactory
67{
68public:
69 CMyComClassFactorySingleton() : m_hrCreate(S_OK){}
70 virtual ~CMyComClassFactorySingleton(){}
71 // IClassFactory
72 STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj)
73 {
74 HRESULT hRes = E_POINTER;
75 if (ppvObj != NULL)
76 {
77 *ppvObj = NULL;
78 // Aggregation is not supported in singleton objects.
79 ATLASSERT(pUnkOuter == NULL);
80 if (pUnkOuter != NULL)
81 hRes = CLASS_E_NOAGGREGATION;
82 else
83 {
84 if (m_hrCreate == S_OK && m_spObj == NULL)
85 {
86 Lock();
87 __try
88 {
89 // Fix: The following If statement was moved inside the __try statement.
90 // Did another thread arrive here first?
91 if (m_hrCreate == S_OK && m_spObj == NULL)
92 {
93 // lock the module to indicate activity
94 // (necessary for the monitor shutdown thread to correctly
95 // terminate the module in case when CreateInstance() fails)
96 _pAtlModule->Lock();
97 CComObjectCached<T> *p;
98 m_hrCreate = CComObjectCached<T>::CreateInstance(&p);
99 if (SUCCEEDED(m_hrCreate))
100 {
101 m_hrCreate = p->QueryInterface(IID_IUnknown, (void**)&m_spObj);
102 if (FAILED(m_hrCreate))
103 {
104 delete p;
105 }
106 }
107 _pAtlModule->Unlock();
108 }
109 }
110 __finally
111 {
112 Unlock();
113 }
114 }
115 if (m_hrCreate == S_OK)
116 {
117 hRes = m_spObj->QueryInterface(riid, ppvObj);
118 }
119 else
120 {
121 hRes = m_hrCreate;
122 }
123 }
124 }
125 return hRes;
126 }
127 HRESULT m_hrCreate;
128 CComPtr<IUnknown> m_spObj;
129};
130
131#endif /* !defined (VBOX_WITH_XPCOM) */
132
133// macros
134////////////////////////////////////////////////////////////////////////////////
135
136/**
137 * Special version of the Assert macro to be used within VirtualBoxBase
138 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template.
139 *
140 * In the debug build, this macro is equivalent to Assert.
141 * In the release build, this macro uses |setError (E_FAIL, ...)| to set the
142 * error info from the asserted expression.
143 *
144 * @see VirtualBoxSupportErrorInfoImpl::setError
145 *
146 * @param expr Expression which should be true.
147 */
148#if defined (DEBUG)
149#define ComAssert(expr) Assert (expr)
150#else
151#define ComAssert(expr) \
152 do { \
153 if (!(expr)) \
154 setError (E_FAIL, "Assertion failed: [%s] at '%s' (%d) in %s.\n" \
155 "Please contact the product vendor!", \
156 #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
157 } while (0)
158#endif
159
160/**
161 * Special version of the AssertMsg macro to be used within VirtualBoxBase
162 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template.
163 *
164 * See ComAssert for more info.
165 *
166 * @param expr Expression which should be true.
167 * @param a printf argument list (in parenthesis).
168 */
169#if defined (DEBUG)
170#define ComAssertMsg(expr, a) AssertMsg (expr, a)
171#else
172#define ComAssertMsg(expr, a) \
173 do { \
174 if (!(expr)) \
175 setError (E_FAIL, "Assertion failed: [%s] at '%s' (%d) in %s.\n" \
176 "%s.\n" \
177 "Please contact the product vendor!", \
178 #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__, Utf8StrFmt a .raw()); \
179 } while (0)
180#endif
181
182/**
183 * Special version of the AssertRC macro to be used within VirtualBoxBase
184 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template.
185 *
186 * See ComAssert for more info.
187 *
188 * @param vrc VBox status code.
189 */
190#if defined (DEBUG)
191#define ComAssertRC(vrc) AssertRC (vrc)
192#else
193#define ComAssertRC(vrc) ComAssertMsgRC (vrc, ("%Rra", vrc))
194#endif
195
196/**
197 * Special version of the AssertMsgRC macro to be used within VirtualBoxBase
198 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template.
199 *
200 * See ComAssert for more info.
201 *
202 * @param vrc VBox status code.
203 * @param msg printf argument list (in parenthesis).
204 */
205#if defined (DEBUG)
206#define ComAssertMsgRC(vrc, msg) AssertMsgRC (vrc, msg)
207#else
208#define ComAssertMsgRC(vrc, msg) ComAssertMsg (RT_SUCCESS (vrc), msg)
209#endif
210
211
212/**
213 * Special version of the AssertFailed macro to be used within VirtualBoxBase
214 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template.
215 *
216 * See ComAssert for more info.
217 */
218#if defined (DEBUG)
219#define ComAssertFailed() AssertFailed()
220#else
221#define ComAssertFailed() \
222 do { \
223 setError (E_FAIL, "Assertion failed at '%s' (%d) in %s.\n" \
224 "Please contact the product vendor!", \
225 __FILE__, __LINE__, __PRETTY_FUNCTION__); \
226 } while (0)
227#endif
228
229/**
230 * Special version of the AssertMsgFailed macro to be used within VirtualBoxBase
231 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template.
232 *
233 * See ComAssert for more info.
234 *
235 * @param a printf argument list (in parenthesis).
236 */
237#if defined (DEBUG)
238#define ComAssertMsgFailed(a) AssertMsgFailed(a)
239#else
240#define ComAssertMsgFailed(a) \
241 do { \
242 setError (E_FAIL, "Assertion failed at '%s' (%d) in %s.\n" \
243 "%s.\n" \
244 "Please contact the product vendor!", \
245 __FILE__, __LINE__, __PRETTY_FUNCTION__, Utf8StrFmt a .raw()); \
246 } while (0)
247#endif
248
249/**
250 * Special version of the ComAssertMsgFailed macro that additionally takes
251 * line number, file and function arguments to inject an assertion position
252 * that differs from the position where this macro is instantiated.
253 *
254 * @param a printf argument list (in parenthesis).
255 * @param file, line, func Line number (int), file and function (const char *).
256 */
257#if defined (DEBUG)
258#define ComAssertMsgFailedPos(a, file, line, func) \
259 do { \
260 AssertMsg1 ((const char *) 0, line, file, func); \
261 AssertMsg2 a; \
262 AssertBreakpoint(); \
263 } while (0)
264#else
265#define ComAssertMsgFailedPos(a, file, line, func) \
266 do { \
267 setError (E_FAIL, \
268 "Assertion failed at '%s' (%d) in %s.\n" \
269 "%s.\n" \
270 "Please contact the product vendor!", \
271 file, line, func, Utf8StrFmt a .raw()); \
272 } while (0)
273#endif
274
275/**
276 * Special version of the AssertComRC macro to be used within VirtualBoxBase
277 * subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template.
278 *
279 * See ComAssert for more info.
280 *
281 * @param rc COM result code
282 */
283#if defined (DEBUG)
284#define ComAssertComRC(rc) AssertComRC (rc)
285#else
286#define ComAssertComRC(rc) ComAssertMsg (SUCCEEDED (rc), ("COM RC = %Rhrc (0x%08X)", (rc), (rc)))
287#endif
288
289
290/** Special version of ComAssert that returns ret if expr fails */
291#define ComAssertRet(expr, ret) \
292 do { ComAssert (expr); if (!(expr)) return (ret); } while (0)
293/** Special version of ComAssertMsg that returns ret if expr fails */
294#define ComAssertMsgRet(expr, a, ret) \
295 do { ComAssertMsg (expr, a); if (!(expr)) return (ret); } while (0)
296/** Special version of ComAssertRC that returns ret if vrc does not succeed */
297#define ComAssertRCRet(vrc, ret) \
298 do { ComAssertRC (vrc); if (!RT_SUCCESS (vrc)) return (ret); } while (0)
299/** Special version of ComAssertMsgRC that returns ret if vrc does not succeed */
300#define ComAssertMsgRCRet(vrc, msg, ret) \
301 do { ComAssertMsgRC (vrc, msg); if (!RT_SUCCESS (vrc)) return (ret); } while (0)
302/** Special version of ComAssertFailed that returns ret */
303#define ComAssertFailedRet(ret) \
304 do { ComAssertFailed(); return (ret); } while (0)
305/** Special version of ComAssertMsgFailed that returns ret */
306#define ComAssertMsgFailedRet(msg, ret) \
307 do { ComAssertMsgFailed (msg); return (ret); } while (0)
308/** Special version of ComAssertComRC that returns ret if rc does not succeed */
309#define ComAssertComRCRet(rc, ret) \
310 do { ComAssertComRC (rc); if (!SUCCEEDED (rc)) return (ret); } while (0)
311/** Special version of ComAssertComRC that returns rc if rc does not succeed */
312#define ComAssertComRCRetRC(rc) \
313 do { ComAssertComRC (rc); if (!SUCCEEDED (rc)) return (rc); } while (0)
314
315
316/** Special version of ComAssert that evaluates eval and breaks if expr fails */
317#define ComAssertBreak(expr, eval) \
318 if (1) { ComAssert (expr); if (!(expr)) { eval; break; } } else do {} while (0)
319/** Special version of ComAssertMsg that evaluates eval and breaks if expr fails */
320#define ComAssertMsgBreak(expr, a, eval) \
321 if (1) { ComAssertMsg (expr, a); if (!(expr)) { eval; break; } } else do {} while (0)
322/** Special version of ComAssertRC that evaluates eval and breaks if vrc does not succeed */
323#define ComAssertRCBreak(vrc, eval) \
324 if (1) { ComAssertRC (vrc); if (!RT_SUCCESS (vrc)) { eval; break; } } else do {} while (0)
325/** Special version of ComAssertMsgRC that evaluates eval and breaks if vrc does not succeed */
326#define ComAssertMsgRCBreak(vrc, msg, eval) \
327 if (1) { ComAssertMsgRC (vrc, msg); if (!RT_SUCCESS (vrc)) { eval; break; } } else do {} while (0)
328/** Special version of ComAssertFailed that evaluates eval and breaks */
329#define ComAssertFailedBreak(eval) \
330 if (1) { ComAssertFailed(); { eval; break; } } else do {} while (0)
331/** Special version of ComAssertMsgFailed that evaluates eval and breaks */
332#define ComAssertMsgFailedBreak(msg, eval) \
333 if (1) { ComAssertMsgFailed (msg); { eval; break; } } else do {} while (0)
334/** Special version of ComAssertComRC that evaluates eval and breaks if rc does not succeed */
335#define ComAssertComRCBreak(rc, eval) \
336 if (1) { ComAssertComRC (rc); if (!SUCCEEDED (rc)) { eval; break; } } else do {} while (0)
337/** Special version of ComAssertComRC that just breaks if rc does not succeed */
338#define ComAssertComRCBreakRC(rc) \
339 if (1) { ComAssertComRC (rc); if (!SUCCEEDED (rc)) { break; } } else do {} while (0)
340
341
342/** Special version of ComAssert that evaluates eval and throws it if expr fails */
343#define ComAssertThrow(expr, eval) \
344 if (1) { ComAssert (expr); if (!(expr)) { throw (eval); } } else do {} while (0)
345/** Special version of ComAssertMsg that evaluates eval and throws it if expr fails */
346#define ComAssertMsgThrow(expr, a, eval) \
347 if (1) { ComAssertMsg (expr, a); if (!(expr)) { throw (eval); } } else do {} while (0)
348/** Special version of ComAssertRC that evaluates eval and throws it if vrc does not succeed */
349#define ComAssertRCThrow(vrc, eval) \
350 if (1) { ComAssertRC (vrc); if (!RT_SUCCESS (vrc)) { throw (eval); } } else do {} while (0)
351/** Special version of ComAssertMsgRC that evaluates eval and throws it if vrc does not succeed */
352#define ComAssertMsgRCThrow(vrc, msg, eval) \
353 if (1) { ComAssertMsgRC (vrc, msg); if (!RT_SUCCESS (vrc)) { throw (eval); } } else do {} while (0)
354/** Special version of ComAssertFailed that evaluates eval and throws it */
355#define ComAssertFailedThrow(eval) \
356 if (1) { ComAssertFailed(); { throw (eval); } } else do {} while (0)
357/** Special version of ComAssertMsgFailed that evaluates eval and throws it */
358#define ComAssertMsgFailedThrow(msg, eval) \
359 if (1) { ComAssertMsgFailed (msg); { throw (eval); } } else do {} while (0)
360/** Special version of ComAssertComRC that evaluates eval and throws it if rc does not succeed */
361#define ComAssertComRCThrow(rc, eval) \
362 if (1) { ComAssertComRC (rc); if (!SUCCEEDED (rc)) { throw (eval); } } else do {} while (0)
363/** Special version of ComAssertComRC that just throws rc if rc does not succeed */
364#define ComAssertComRCThrowRC(rc) \
365 if (1) { ComAssertComRC (rc); if (!SUCCEEDED (rc)) { throw rc; } } else do {} while (0)
366
367////////////////////////////////////////////////////////////////////////////////
368
369/**
370 * Checks that the pointer argument is not NULL and returns E_INVALIDARG +
371 * extended error info on failure.
372 * @param arg Input pointer-type argument (strings, interface pointers...)
373 */
374#define CheckComArgNotNull(arg) \
375 do { \
376 if ((arg) == NULL) \
377 return setError (E_INVALIDARG, tr ("Argument %s is NULL"), #arg); \
378 } while (0)
379
380/**
381 * Checks that safe array argument is not NULL and returns E_INVALIDARG +
382 * extended error info on failure.
383 * @param arg Input safe array argument (strings, interface pointers...)
384 */
385#define CheckComArgSafeArrayNotNull(arg) \
386 do { \
387 if (ComSafeArrayInIsNull (arg)) \
388 return setError (E_INVALIDARG, tr ("Argument %s is NULL"), #arg); \
389 } while (0)
390
391/**
392 * Checks that the string argument is not a NULL or empty string and returns
393 * E_INVALIDARG + extended error info on failure.
394 * @param arg Input string argument (BSTR etc.).
395 */
396#define CheckComArgStrNotEmptyOrNull(arg) \
397 do { \
398 if ((arg) == NULL || *(arg) == '\0') \
399 return setError (E_INVALIDARG, \
400 tr ("Argument %s is empty or NULL"), #arg); \
401 } while (0)
402
403/**
404 * Checks that the given expression (that must involve the argument) is true and
405 * returns E_INVALIDARG + extended error info on failure.
406 * @param arg Argument.
407 * @param expr Expression to evaluate.
408 */
409#define CheckComArgExpr(arg, expr) \
410 do { \
411 if (!(expr)) \
412 return setError (E_INVALIDARG, \
413 tr ("Argument %s is invalid (must be %s)"), #arg, #expr); \
414 } while (0)
415
416/**
417 * Checks that the given expression (that must involve the argument) is true and
418 * returns E_INVALIDARG + extended error info on failure. The error message must
419 * be customized.
420 * @param arg Argument.
421 * @param expr Expression to evaluate.
422 * @param msg Parenthesized printf-like expression (must start with a verb,
423 * like "must be one of...", "is not within...").
424 */
425#define CheckComArgExprMsg(arg, expr, msg) \
426 do { \
427 if (!(expr)) \
428 return setError (E_INVALIDARG, tr ("Argument %s %s"), \
429 #arg, Utf8StrFmt msg .raw()); \
430 } while (0)
431
432/**
433 * Checks that the given pointer to an output argument is valid and returns
434 * E_POINTER + extended error info otherwise.
435 * @param arg Pointer argument.
436 */
437#define CheckComArgOutPointerValid(arg) \
438 do { \
439 if (!VALID_PTR (arg)) \
440 return setError (E_POINTER, \
441 tr ("Output argument %s points to invalid memory location (%p)"), \
442 #arg, (void *) (arg)); \
443 } while (0)
444
445/**
446 * Checks that the given pointer to an output safe array argument is valid and
447 * returns E_POINTER + extended error info otherwise.
448 * @param arg Safe array argument.
449 */
450#define CheckComArgOutSafeArrayPointerValid(arg) \
451 do { \
452 if (ComSafeArrayOutIsNull (arg)) \
453 return setError (E_POINTER, \
454 tr ("Output argument %s points to invalid memory location (%p)"), \
455 #arg, (void *) (arg)); \
456 } while (0)
457
458/**
459 * Sets the extended error info and returns E_NOTIMPL.
460 */
461#define ReturnComNotImplemented() \
462 do { \
463 return setError (E_NOTIMPL, tr ("Method %s is not implemented"), __FUNCTION__); \
464 } while (0)
465
466////////////////////////////////////////////////////////////////////////////////
467
468/**
469 * Declares an empty constructor and destructor for the given class.
470 * This is useful to prevent the compiler from generating the default
471 * ctor and dtor, which in turn allows to use forward class statements
472 * (instead of including their header files) when declaring data members of
473 * non-fundamental types with constructors (which are always called implicitly
474 * by constructors and by the destructor of the class).
475 *
476 * This macro is to be placed within (the public section of) the class
477 * declaration. Its counterpart, DEFINE_EMPTY_CTOR_DTOR, must be placed
478 * somewhere in one of the translation units (usually .cpp source files).
479 *
480 * @param cls class to declare a ctor and dtor for
481 */
482#define DECLARE_EMPTY_CTOR_DTOR(cls) cls(); ~cls();
483
484/**
485 * Defines an empty constructor and destructor for the given class.
486 * See DECLARE_EMPTY_CTOR_DTOR for more info.
487 */
488#define DEFINE_EMPTY_CTOR_DTOR(cls) \
489 cls::cls () {}; cls::~cls () {};
490
491////////////////////////////////////////////////////////////////////////////////
492
493namespace stdx
494{
495 /**
496 * A wrapper around the container that owns pointers it stores.
497 *
498 * @note
499 * Ownership is recognized only when destructing the container!
500 * Pointers are not deleted when erased using erase() etc.
501 *
502 * @param container
503 * class that meets Container requirements (for example, an instance of
504 * std::list<>, std::vector<> etc.). The given class must store
505 * pointers (for example, std::list <MyType *>).
506 */
507 template <typename container>
508 class ptr_container : public container
509 {
510 public:
511 ~ptr_container()
512 {
513 for (typename container::iterator it = container::begin();
514 it != container::end();
515 ++ it)
516 delete (*it);
517 }
518 };
519}
520
521////////////////////////////////////////////////////////////////////////////////
522
523/**
524 * Abstract base class for all component classes implementing COM
525 * interfaces of the VirtualBox COM library.
526 *
527 * Declares functionality that should be available in all components.
528 *
529 * Note that this class is always subclassed using the virtual keyword so
530 * that only one instance of its VTBL and data is present in each derived class
531 * even in case if VirtualBoxBaseProto appears more than once among base classes
532 * of the particular component as a result of multiple inheritance.
533 *
534 * This makes it possible to have intermediate base classes used by several
535 * components that implement some common interface functionality but still let
536 * the final component classes choose what VirtualBoxBase variant it wants to
537 * use.
538 *
539 * Among the basic functionality implemented by this class is the primary object
540 * state that indicates if the object is ready to serve the calls, and if not,
541 * what stage it is currently at. Here is the primary state diagram:
542 *
543 * +-------------------------------------------------------+
544 * | |
545 * | (InitFailed) -----------------------+ |
546 * | ^ | |
547 * v | v |
548 * [*] ---> NotReady ----> (InInit) -----> Ready -----> (InUninit) ----+
549 * ^ | ^ | ^
550 * | v | v |
551 * | Limited | (MayUninit) --> (WillUninit)
552 * | | | |
553 * +-------+ +-------+
554 *
555 * The object is fully operational only when its state is Ready. The Limited
556 * state means that only some vital part of the object is operational, and it
557 * requires some sort of reinitialization to become fully operational. The
558 * NotReady state means the object is basically dead: it either was not yet
559 * initialized after creation at all, or was uninitialized and is waiting to be
560 * destroyed when the last reference to it is released. All other states are
561 * transitional.
562 *
563 * The NotReady->InInit->Ready, NotReady->InInit->Limited and
564 * NotReady->InInit->InitFailed transition is done by the AutoInitSpan smart
565 * class.
566 *
567 * The Limited->InInit->Ready, Limited->InInit->Limited and
568 * Limited->InInit->InitFailed transition is done by the AutoReinitSpan smart
569 * class.
570 *
571 * The Ready->InUninit->NotReady, InitFailed->InUninit->NotReady and
572 * WillUninit->InUninit->NotReady transitions are done by the AutoUninitSpan
573 * smart class.
574 *
575 * The Ready->MayUninit->Ready and Ready->MayUninit->WillUninit transitions are
576 * done by the AutoMayUninitSpan smart class.
577 *
578 * In order to maintain the primary state integrity and declared functionality
579 * all subclasses must:
580 *
581 * 1) Use the above Auto*Span classes to perform state transitions. See the
582 * individual class descriptions for details.
583 *
584 * 2) All public methods of subclasses (i.e. all methods that can be called
585 * directly, not only from within other methods of the subclass) must have a
586 * standard prolog as described in the AutoCaller and AutoLimitedCaller
587 * documentation. Alternatively, they must use addCaller()/releaseCaller()
588 * directly (and therefore have both the prolog and the epilog), but this is
589 * not recommended.
590 */
591class ATL_NO_VTABLE VirtualBoxBaseProto : public Lockable
592{
593public:
594
595 enum State { NotReady, Ready, InInit, InUninit, InitFailed, Limited,
596 MayUninit, WillUninit };
597
598protected:
599
600 VirtualBoxBaseProto();
601 virtual ~VirtualBoxBaseProto();
602
603public:
604
605 // util::Lockable interface
606 virtual RWLockHandle *lockHandle() const;
607
608 /**
609 * Unintialization method.
610 *
611 * Must be called by all final implementations (component classes) when the
612 * last reference to the object is released, before calling the destructor.
613 *
614 * This method is also automatically called by the uninit() method of this
615 * object's parent if this object is a dependent child of a class derived
616 * from VirtualBoxBaseWithChildren (see
617 * VirtualBoxBaseWithChildren::addDependentChild).
618 *
619 * @note Never call this method the AutoCaller scope or after the
620 * #addCaller() call not paired by #releaseCaller() because it is a
621 * guaranteed deadlock. See AutoUninitSpan for details.
622 */
623 virtual void uninit() {}
624
625 virtual HRESULT addCaller (State *aState = NULL, bool aLimited = false);
626 virtual void releaseCaller();
627
628 /**
629 * Adds a limited caller. This method is equivalent to doing
630 * <tt>addCaller (aState, true)</tt>, but it is preferred because provides
631 * better self-descriptiveness. See #addCaller() for more info.
632 */
633 HRESULT addLimitedCaller (State *aState = NULL)
634 {
635 return addCaller (aState, true /* aLimited */);
636 }
637
638 /**
639 * Smart class that automatically increases the number of callers of the
640 * given VirtualBoxBase object when an instance is constructed and decreases
641 * it back when the created instance goes out of scope (i.e. gets destroyed).
642 *
643 * If #rc() returns a failure after the instance creation, it means that
644 * the managed VirtualBoxBase object is not Ready, or in any other invalid
645 * state, so that the caller must not use the object and can return this
646 * failed result code to the upper level.
647 *
648 * See VirtualBoxBase::addCaller(), VirtualBoxBase::addLimitedCaller() and
649 * VirtualBoxBase::releaseCaller() for more details about object callers.
650 *
651 * @param aLimited |false| if this template should use
652 * VirtualiBoxBase::addCaller() calls to add callers, or
653 * |true| if VirtualiBoxBase::addLimitedCaller() should be
654 * used.
655 *
656 * @note It is preferable to use the AutoCaller and AutoLimitedCaller
657 * classes than specify the @a aLimited argument, for better
658 * self-descriptiveness.
659 */
660 template <bool aLimited>
661 class AutoCallerBase
662 {
663 public:
664
665 /**
666 * Increases the number of callers of the given object by calling
667 * VirtualBoxBase::addCaller().
668 *
669 * @param aObj Object to add a caller to. If NULL, this
670 * instance is effectively turned to no-op (where
671 * rc() will return S_OK and state() will be
672 * NotReady).
673 */
674 AutoCallerBase (VirtualBoxBaseProto *aObj)
675 : mObj (aObj)
676 , mRC (S_OK)
677 , mState (NotReady)
678 {
679 if (mObj)
680 mRC = mObj->addCaller (&mState, aLimited);
681 }
682
683 /**
684 * If the number of callers was successfully increased, decreases it
685 * using VirtualBoxBase::releaseCaller(), otherwise does nothing.
686 */
687 ~AutoCallerBase()
688 {
689 if (mObj && SUCCEEDED (mRC))
690 mObj->releaseCaller();
691 }
692
693 /**
694 * Stores the result code returned by VirtualBoxBase::addCaller() after
695 * instance creation or after the last #add() call. A successful result
696 * code means the number of callers was successfully increased.
697 */
698 HRESULT rc() const { return mRC; }
699
700 /**
701 * Returns |true| if |SUCCEEDED (rc())| is |true|, for convenience.
702 * |true| means the number of callers was successfully increased.
703 */
704 bool isOk() const { return SUCCEEDED (mRC); }
705
706 /**
707 * Stores the object state returned by VirtualBoxBase::addCaller() after
708 * instance creation or after the last #add() call.
709 */
710 State state() const { return mState; }
711
712 /**
713 * Temporarily decreases the number of callers of the managed object.
714 * May only be called if #isOk() returns |true|. Note that #rc() will
715 * return E_FAIL after this method succeeds.
716 */
717 void release()
718 {
719 Assert (SUCCEEDED (mRC));
720 if (SUCCEEDED (mRC))
721 {
722 if (mObj)
723 mObj->releaseCaller();
724 mRC = E_FAIL;
725 }
726 }
727
728 /**
729 * Restores the number of callers decreased by #release(). May only be
730 * called after #release().
731 */
732 void add()
733 {
734 Assert (!SUCCEEDED (mRC));
735 if (mObj && !SUCCEEDED (mRC))
736 mRC = mObj->addCaller (&mState, aLimited);
737 }
738
739 /**
740 * Attaches another object to this caller instance.
741 * The previous object's caller is released before the new one is added.
742 *
743 * @param aObj New object to attach, may be @c NULL.
744 */
745 void attach (VirtualBoxBaseProto *aObj)
746 {
747 /* detect simple self-reattachment */
748 if (mObj != aObj)
749 {
750 if (mObj && SUCCEEDED (mRC))
751 release();
752 mObj = aObj;
753 add();
754 }
755 }
756
757 /** Verbose equivalent to <tt>attach (NULL)</tt>. */
758 void detach() { attach (NULL); }
759
760 private:
761
762 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (AutoCallerBase)
763 DECLARE_CLS_NEW_DELETE_NOOP (AutoCallerBase)
764
765 VirtualBoxBaseProto *mObj;
766 HRESULT mRC;
767 State mState;
768 };
769
770 /**
771 * Smart class that automatically increases the number of normal
772 * (non-limited) callers of the given VirtualBoxBase object when an instance
773 * is constructed and decreases it back when the created instance goes out
774 * of scope (i.e. gets destroyed).
775 *
776 * A typical usage pattern to declare a normal method of some object (i.e. a
777 * method that is valid only when the object provides its full
778 * functionality) is:
779 * <code>
780 * STDMETHODIMP Component::Foo()
781 * {
782 * AutoCaller autoCaller (this);
783 * CheckComRCReturnRC (autoCaller.rc());
784 * ...
785 * </code>
786 *
787 * Using this class is equivalent to using the AutoCallerBase template with
788 * the @a aLimited argument set to |false|, but this class is preferred
789 * because provides better self-descriptiveness.
790 *
791 * See AutoCallerBase for more information about auto caller functionality.
792 */
793 typedef AutoCallerBase <false> AutoCaller;
794
795 /**
796 * Smart class that automatically increases the number of limited callers of
797 * the given VirtualBoxBase object when an instance is constructed and
798 * decreases it back when the created instance goes out of scope (i.e. gets
799 * destroyed).
800 *
801 * A typical usage pattern to declare a limited method of some object (i.e.
802 * a method that is valid even if the object doesn't provide its full
803 * functionality) is:
804 * <code>
805 * STDMETHODIMP Component::Bar()
806 * {
807 * AutoLimitedCaller autoCaller (this);
808 * CheckComRCReturnRC (autoCaller.rc());
809 * ...
810 * </code>
811 *
812 * Using this class is equivalent to using the AutoCallerBase template with
813 * the @a aLimited argument set to |true|, but this class is preferred
814 * because provides better self-descriptiveness.
815 *
816 * See AutoCallerBase for more information about auto caller functionality.
817 */
818 typedef AutoCallerBase <true> AutoLimitedCaller;
819
820protected:
821
822 /**
823 * Smart class to enclose the state transition NotReady->InInit->Ready.
824 *
825 * The purpose of this span is to protect object initialization.
826 *
827 * Instances must be created as a stack-based variable taking |this| pointer
828 * as the argument at the beginning of init() methods of VirtualBoxBase
829 * subclasses. When this variable is created it automatically places the
830 * object to the InInit state.
831 *
832 * When the created variable goes out of scope (i.e. gets destroyed) then,
833 * depending on the result status of this initialization span, it either
834 * places the object to Ready or Limited state or calls the object's
835 * VirtualBoxBase::uninit() method which is supposed to place the object
836 * back to the NotReady state using the AutoUninitSpan class.
837 *
838 * The initial result status of the initialization span is determined by the
839 * @a aResult argument of the AutoInitSpan constructor (Result::Failed by
840 * default). Inside the initialization span, the success status can be set
841 * to Result::Succeeded using #setSucceeded(), to to Result::Limited using
842 * #setLimited() or to Result::Failed using #setFailed(). Please don't
843 * forget to set the correct success status before getting the AutoInitSpan
844 * variable destroyed (for example, by performing an early return from
845 * the init() method)!
846 *
847 * Note that if an instance of this class gets constructed when the object
848 * is in the state other than NotReady, #isOk() returns |false| and methods
849 * of this class do nothing: the state transition is not performed.
850 *
851 * A typical usage pattern is:
852 * <code>
853 * HRESULT Component::init()
854 * {
855 * AutoInitSpan autoInitSpan (this);
856 * AssertReturn (autoInitSpan.isOk(), E_FAIL);
857 * ...
858 * if (FAILED (rc))
859 * return rc;
860 * ...
861 * if (SUCCEEDED (rc))
862 * autoInitSpan.setSucceeded();
863 * return rc;
864 * }
865 * </code>
866 *
867 * @note Never create instances of this class outside init() methods of
868 * VirtualBoxBase subclasses and never pass anything other than |this|
869 * as the argument to the constructor!
870 */
871 class AutoInitSpan
872 {
873 public:
874
875 enum Result { Failed = 0x0, Succeeded = 0x1, Limited = 0x2 };
876
877 AutoInitSpan (VirtualBoxBaseProto *aObj, Result aResult = Failed);
878 ~AutoInitSpan();
879
880 /**
881 * Returns |true| if this instance has been created at the right moment
882 * (when the object was in the NotReady state) and |false| otherwise.
883 */
884 bool isOk() const { return mOk; }
885
886 /**
887 * Sets the initialization status to Succeeded to indicates successful
888 * initialization. The AutoInitSpan destructor will place the managed
889 * VirtualBoxBase object to the Ready state.
890 */
891 void setSucceeded() { mResult = Succeeded; }
892
893 /**
894 * Sets the initialization status to Succeeded to indicate limited
895 * (partly successful) initialization. The AutoInitSpan destructor will
896 * place the managed VirtualBoxBase object to the Limited state.
897 */
898 void setLimited() { mResult = Limited; }
899
900 /**
901 * Sets the initialization status to Failure to indicates failed
902 * initialization. The AutoInitSpan destructor will place the managed
903 * VirtualBoxBase object to the InitFailed state and will automatically
904 * call its uninit() method which is supposed to place the object back
905 * to the NotReady state using AutoUninitSpan.
906 */
907 void setFailed() { mResult = Failed; }
908
909 /** Returns the current initialization result. */
910 Result result() { return mResult; }
911
912 private:
913
914 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (AutoInitSpan)
915 DECLARE_CLS_NEW_DELETE_NOOP (AutoInitSpan)
916
917 VirtualBoxBaseProto *mObj;
918 Result mResult : 3; // must be at least total number of bits + 1 (sign)
919 bool mOk : 1;
920 };
921
922 /**
923 * Smart class to enclose the state transition Limited->InInit->Ready.
924 *
925 * The purpose of this span is to protect object re-initialization.
926 *
927 * Instances must be created as a stack-based variable taking |this| pointer
928 * as the argument at the beginning of methods of VirtualBoxBase
929 * subclasses that try to re-initialize the object to bring it to the Ready
930 * state (full functionality) after partial initialization (limited
931 * functionality). When this variable is created, it automatically places
932 * the object to the InInit state.
933 *
934 * When the created variable goes out of scope (i.e. gets destroyed),
935 * depending on the success status of this initialization span, it either
936 * places the object to the Ready state or brings it back to the Limited
937 * state.
938 *
939 * The initial success status of the re-initialization span is |false|. In
940 * order to make it successful, #setSucceeded() must be called before the
941 * instance is destroyed.
942 *
943 * Note that if an instance of this class gets constructed when the object
944 * is in the state other than Limited, #isOk() returns |false| and methods
945 * of this class do nothing: the state transition is not performed.
946 *
947 * A typical usage pattern is:
948 * <code>
949 * HRESULT Component::reinit()
950 * {
951 * AutoReinitSpan autoReinitSpan (this);
952 * AssertReturn (autoReinitSpan.isOk(), E_FAIL);
953 * ...
954 * if (FAILED (rc))
955 * return rc;
956 * ...
957 * if (SUCCEEDED (rc))
958 * autoReinitSpan.setSucceeded();
959 * return rc;
960 * }
961 * </code>
962 *
963 * @note Never create instances of this class outside re-initialization
964 * methods of VirtualBoxBase subclasses and never pass anything other than
965 * |this| as the argument to the constructor!
966 */
967 class AutoReinitSpan
968 {
969 public:
970
971 AutoReinitSpan (VirtualBoxBaseProto *aObj);
972 ~AutoReinitSpan();
973
974 /**
975 * Returns |true| if this instance has been created at the right moment
976 * (when the object was in the Limited state) and |false| otherwise.
977 */
978 bool isOk() const { return mOk; }
979
980 /**
981 * Sets the re-initialization status to Succeeded to indicates
982 * successful re-initialization. The AutoReinitSpan destructor will place
983 * the managed VirtualBoxBase object to the Ready state.
984 */
985 void setSucceeded() { mSucceeded = true; }
986
987 private:
988
989 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (AutoReinitSpan)
990 DECLARE_CLS_NEW_DELETE_NOOP (AutoReinitSpan)
991
992 VirtualBoxBaseProto *mObj;
993 bool mSucceeded : 1;
994 bool mOk : 1;
995 };
996
997 /**
998 * Smart class to enclose the state transition Ready->InUnnit->NotReady,
999 * InitFailed->InUnnit->NotReady or WillUninit->InUnnit->NotReady.
1000 *
1001 * The purpose of this span is to protect object uninitialization.
1002 *
1003 * Instances must be created as a stack-based variable taking |this| pointer
1004 * as the argument at the beginning of uninit() methods of VirtualBoxBase
1005 * subclasses. When this variable is created it automatically places the
1006 * object to the InUninit state, unless it is already in the NotReady state
1007 * as indicated by #uninitDone() returning |true|. In the latter case, the
1008 * uninit() method must immediately return because there should be nothing
1009 * to uninitialize.
1010 *
1011 * When this variable goes out of scope (i.e. gets destroyed), it places the
1012 * object to NotReady state.
1013 *
1014 * A typical usage pattern is:
1015 * <code>
1016 * void Component::uninit()
1017 * {
1018 * AutoUninitSpan autoUninitSpan (this);
1019 * if (autoUninitSpan.uninitDone())
1020 * return;
1021 * ...
1022 * }
1023 * </code>
1024 *
1025 * @note The constructor of this class blocks the current thread execution
1026 * until the number of callers added to the object using #addCaller()
1027 * or AutoCaller drops to zero. For this reason, it is forbidden to
1028 * create instances of this class (or call uninit()) within the
1029 * AutoCaller or #addCaller() scope because it is a guaranteed
1030 * deadlock.
1031 *
1032 * @note Never create instances of this class outside uninit() methods and
1033 * never pass anything other than |this| as the argument to the
1034 * constructor!
1035 */
1036 class AutoUninitSpan
1037 {
1038 public:
1039
1040 AutoUninitSpan (VirtualBoxBaseProto *aObj);
1041 ~AutoUninitSpan();
1042
1043 /** |true| when uninit() is called as a result of init() failure */
1044 bool initFailed() { return mInitFailed; }
1045
1046 /** |true| when uninit() has already been called (so the object is NotReady) */
1047 bool uninitDone() { return mUninitDone; }
1048
1049 private:
1050
1051 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (AutoUninitSpan)
1052 DECLARE_CLS_NEW_DELETE_NOOP (AutoUninitSpan)
1053
1054 VirtualBoxBaseProto *mObj;
1055 bool mInitFailed : 1;
1056 bool mUninitDone : 1;
1057 };
1058
1059 /**
1060 * Smart class to enclose the state transition Ready->MayUninit->NotReady or
1061 * Ready->MayUninit->WillUninit.
1062 *
1063 * The purpose of this span is to safely check if unintialization is
1064 * possible at the given moment and seamlessly perform it if so.
1065 *
1066 * Instances must be created as a stack-based variable taking |this| pointer
1067 * as the argument at the beginning of methods of VirtualBoxBase
1068 * subclasses that want to uninitialize the object if a necessary set of
1069 * criteria is met and leave it Ready otherwise.
1070 *
1071 * When this variable is created it automatically places the object to the
1072 * MayUninit state if it is Ready, does nothing but returns |true| in
1073 * response to #alreadyInProgress() if it is already in MayUninit, or
1074 * returns a failure in response to #rc() in any other case. The example
1075 * below shows how the user must react in latter two cases.
1076 *
1077 * When this variable goes out of scope (i.e. gets destroyed), it places the
1078 * object back to Ready state unless #acceptUninit() is called in which case
1079 * the object is placed to WillUninit state and uninit() is immediately
1080 * called after that.
1081 *
1082 * A typical usage pattern is:
1083 * <code>
1084 * void Component::uninit()
1085 * {
1086 * AutoMayUninitSpan mayUninitSpan (this);
1087 * CheckComRCReturnRC (mayUninitSpan.rc());
1088 * if (mayUninitSpan.alreadyInProgress())
1089 * return S_OK;
1090 * ...
1091 * if (FAILED (rc))
1092 * return rc; // will go back to Ready
1093 * ...
1094 * if (SUCCEEDED (rc))
1095 * mayUninitSpan.acceptUninit(); // will call uninit()
1096 * return rc;
1097 * }
1098 * </code>
1099 *
1100 * @note The constructor of this class blocks the current thread execution
1101 * until the number of callers added to the object using #addCaller()
1102 * or AutoCaller drops to zero. For this reason, it is forbidden to
1103 * create instances of this class (or call uninit()) within the
1104 * AutoCaller or #addCaller() scope because it is a guaranteed
1105 * deadlock.
1106 */
1107 class AutoMayUninitSpan
1108 {
1109 public:
1110
1111 AutoMayUninitSpan (VirtualBoxBaseProto *aObj);
1112 ~AutoMayUninitSpan();
1113
1114 /**
1115 * Returns a failure if the AutoMayUninitSpan variable was constructed
1116 * at an improper time. If there is a failure, do nothing but return
1117 * it to the caller.
1118 */
1119 HRESULT rc() { return mRC; }
1120
1121 /**
1122 * Returns |true| if AutoMayUninitSpan is already in progress on some
1123 * other thread. If it's the case, do nothing but return S_OK to
1124 * the caller.
1125 */
1126 bool alreadyInProgress() { return mAlreadyInProgress; }
1127
1128 /*
1129 * Accepts uninitialization and causes the destructor to go to
1130 * WillUninit state and call uninit() afterwards.
1131 */
1132 void acceptUninit() { mAcceptUninit = true; }
1133
1134 private:
1135
1136 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (AutoMayUninitSpan)
1137 DECLARE_CLS_NEW_DELETE_NOOP (AutoMayUninitSpan)
1138
1139 VirtualBoxBaseProto *mObj;
1140
1141 HRESULT mRC;
1142 bool mAlreadyInProgress : 1;
1143 bool mAcceptUninit : 1;
1144 };
1145
1146 /**
1147 * Returns a lock handle used to protect the primary state fields (used by
1148 * #addCaller(), AutoInitSpan, AutoUninitSpan, etc.). Only intended to be
1149 * used for similar purposes in subclasses. WARNING: NO any other locks may
1150 * be requested while holding this lock!
1151 */
1152 WriteLockHandle *stateLockHandle() { return &mStateLock; }
1153
1154private:
1155
1156 void setState (State aState)
1157 {
1158 Assert (mState != aState);
1159 mState = aState;
1160 mStateChangeThread = RTThreadSelf();
1161 }
1162
1163 /** Primary state of this object */
1164 State mState;
1165 /** Thread that caused the last state change */
1166 RTTHREAD mStateChangeThread;
1167 /** Total number of active calls to this object */
1168 unsigned mCallers;
1169 /** Posted when the number of callers drops to zero */
1170 RTSEMEVENT mZeroCallersSem;
1171 /** Posted when the object goes from InInit/InUninit to some other state */
1172 RTSEMEVENTMULTI mInitUninitSem;
1173 /** Number of threads waiting for mInitUninitDoneSem */
1174 unsigned mInitUninitWaiters;
1175
1176 /** Protects access to state related data members */
1177 WriteLockHandle mStateLock;
1178
1179 /** User-level object lock for subclasses */
1180 mutable RWLockHandle *mObjectLock;
1181};
1182
1183////////////////////////////////////////////////////////////////////////////////
1184
1185/**
1186 * This macro adds the error info support to methods of the VirtualBoxBase
1187 * class (by overriding them). Place it to the public section of the
1188 * VirtualBoxBase subclass and the following methods will set the extended
1189 * error info in case of failure instead of just returning the result code:
1190 *
1191 * <ul>
1192 * <li>VirtualBoxBase::addCaller()
1193 * </ul>
1194 *
1195 * @note The given VirtualBoxBase subclass must also inherit from both
1196 * VirtualBoxSupportErrorInfoImpl and VirtualBoxSupportTranslation templates!
1197 *
1198 * @param C VirtualBoxBase subclass to add the error info support to
1199 */
1200#define VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(C) \
1201 virtual HRESULT addCaller (VirtualBoxBaseProto::State *aState = NULL, \
1202 bool aLimited = false) \
1203 { \
1204 VirtualBoxBaseProto::State state; \
1205 HRESULT rc = VirtualBoxBaseProto::addCaller (&state, aLimited); \
1206 if (FAILED (rc)) \
1207 { \
1208 if (state == VirtualBoxBaseProto::Limited) \
1209 rc = setError (rc, tr ("The object functionality is limited")); \
1210 else \
1211 rc = setError (rc, tr ("The object is not ready")); \
1212 } \
1213 if (aState) \
1214 *aState = state; \
1215 return rc; \
1216 } \
1217
1218////////////////////////////////////////////////////////////////////////////////
1219
1220class ATL_NO_VTABLE VirtualBoxBase
1221 : virtual public VirtualBoxBaseProto
1222#if !defined (VBOX_WITH_XPCOM)
1223 , public CComObjectRootEx <CComMultiThreadModel>
1224#else
1225 , public CComObjectRootEx
1226#endif
1227{
1228
1229public:
1230 VirtualBoxBase()
1231 {}
1232
1233 virtual ~VirtualBoxBase()
1234 {}
1235
1236 /**
1237 * Virtual unintialization method. Called during parent object's
1238 * uninitialization, if the given subclass instance is a dependent child of
1239 * a class derived from VirtualBoxBaseWithChildren (@sa
1240 * VirtualBoxBaseWithChildren::addDependentChild). In this case, this
1241 * method's implementation must call setReady (false),
1242 */
1243 virtual void uninit()
1244 {}
1245
1246 static const char *translate (const char *context, const char *sourceText,
1247 const char *comment = 0);
1248};
1249
1250////////////////////////////////////////////////////////////////////////////////
1251
1252/** Helper for VirtualBoxSupportTranslation. */
1253class VirtualBoxSupportTranslationBase
1254{
1255protected:
1256 static bool cutClassNameFrom__PRETTY_FUNCTION__ (char *aPrettyFunctionName);
1257};
1258
1259/**
1260 * The VirtualBoxSupportTranslation template implements the NLS string
1261 * translation support for the given class.
1262 *
1263 * Translation support is provided by the static #tr() function. This function,
1264 * given a string in UTF-8 encoding, looks up for a translation of the given
1265 * string by calling the VirtualBoxBase::translate() global function which
1266 * receives the name of the enclosing class ("context of translation") as the
1267 * additional argument and returns a translated string based on the currently
1268 * active language.
1269 *
1270 * @param C Class that needs to support the string translation.
1271 *
1272 * @note Every class that wants to use the #tr() function in its own methods
1273 * must inherit from this template, regardless of whether its base class
1274 * (if any) inherits from it or not. Otherwise, the translation service
1275 * will not work correctly. However, the declaration of the derived
1276 * class must contain
1277 * the <tt>COM_SUPPORTTRANSLATION_OVERRIDE (<ClassName>)</tt> macro if one
1278 * of its base classes also inherits from this template (to resolve the
1279 * ambiguity of the #tr() function).
1280 */
1281template <class C>
1282class VirtualBoxSupportTranslation : virtual protected VirtualBoxSupportTranslationBase
1283{
1284public:
1285
1286 /**
1287 * Translates the given text string by calling VirtualBoxBase::translate()
1288 * and passing the name of the C class as the first argument ("context of
1289 * translation") See VirtualBoxBase::translate() for more info.
1290 *
1291 * @param aSourceText String to translate.
1292 * @param aComment Comment to the string to resolve possible
1293 * ambiguities (NULL means no comment).
1294 *
1295 * @return Translated version of the source string in UTF-8 encoding, or
1296 * the source string itself if the translation is not found in the
1297 * specified context.
1298 */
1299 inline static const char *tr (const char *aSourceText,
1300 const char *aComment = NULL)
1301 {
1302 return VirtualBoxBase::translate (className(), aSourceText, aComment);
1303 }
1304
1305protected:
1306
1307 static const char *className()
1308 {
1309 static char fn [sizeof (__PRETTY_FUNCTION__) + 1];
1310 if (!sClassName)
1311 {
1312 strcpy (fn, __PRETTY_FUNCTION__);
1313 cutClassNameFrom__PRETTY_FUNCTION__ (fn);
1314 sClassName = fn;
1315 }
1316 return sClassName;
1317 }
1318
1319private:
1320
1321 static const char *sClassName;
1322};
1323
1324template <class C>
1325const char *VirtualBoxSupportTranslation<C>::sClassName = NULL;
1326
1327/**
1328 * This macro must be invoked inside the public section of the declaration of
1329 * the class inherited from the VirtualBoxSupportTranslation template in case
1330 * if one of its other base classes also inherits from that template. This is
1331 * necessary to resolve the ambiguity of the #tr() function.
1332 *
1333 * @param C Class that inherits the VirtualBoxSupportTranslation template
1334 * more than once (through its other base clases).
1335 */
1336#define VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE(C) \
1337 inline static const char *tr (const char *aSourceText, \
1338 const char *aComment = NULL) \
1339 { \
1340 return VirtualBoxSupportTranslation<C>::tr (aSourceText, aComment); \
1341 }
1342
1343/**
1344 * Dummy macro that is used to shut down Qt's lupdate tool warnings in some
1345 * situations. This macro needs to be present inside (better at the very
1346 * beginning) of the declaration of the class that inherits from
1347 * VirtualBoxSupportTranslation template, to make lupdate happy.
1348 */
1349#define Q_OBJECT
1350
1351////////////////////////////////////////////////////////////////////////////////
1352
1353/**
1354 * Helper for the VirtualBoxSupportErrorInfoImpl template.
1355 */
1356/// @todo switch to com::SupportErrorInfo* and remove
1357class VirtualBoxSupportErrorInfoImplBase
1358{
1359 static HRESULT setErrorInternal (HRESULT aResultCode, const GUID &aIID,
1360 const Bstr &aComponent, const Bstr &aText,
1361 bool aWarning, bool aLogIt);
1362
1363protected:
1364
1365 /**
1366 * The MultiResult class is a com::FWResult enhancement that also acts as a
1367 * switch to turn on multi-error mode for #setError() or #setWarning()
1368 * calls.
1369 *
1370 * When an instance of this class is created, multi-error mode is turned on
1371 * for the current thread and the turn-on counter is increased by one. In
1372 * multi-error mode, a call to #setError() or #setWarning() does not
1373 * overwrite the current error or warning info object possibly set on the
1374 * current thread by other method calls, but instead it stores this old
1375 * object in the IVirtualBoxErrorInfo::next attribute of the new error
1376 * object being set.
1377 *
1378 * This way, error/warning objects are stacked together and form a chain of
1379 * errors where the most recent error is the first one retrieved by the
1380 * calling party, the preceding error is what the
1381 * IVirtualBoxErrorInfo::next attribute of the first error points to, and so
1382 * on, up to the first error or warning occurred which is the last in the
1383 * chain. See IVirtualBoxErrorInfo documentation for more info.
1384 *
1385 * When the instance of the MultiResult class goes out of scope and gets
1386 * destroyed, it automatically decreases the turn-on counter by one. If
1387 * the counter drops to zero, multi-error mode for the current thread is
1388 * turned off and the thread switches back to single-error mode where every
1389 * next error or warning object overwrites the previous one.
1390 *
1391 * Note that the caller of a COM method uses a non-S_OK result code to
1392 * decide if the method has returned an error (negative codes) or a warning
1393 * (positive non-zero codes) and will query extended error info only in
1394 * these two cases. However, since multi-error mode implies that the method
1395 * doesn't return control return to the caller immediately after the first
1396 * error or warning but continues its execution, the functionality provided
1397 * by the base com::FWResult class becomes very useful because it allows to
1398 * preserve the error or the warning result code even if it is later assigned
1399 * a S_OK value multiple times. See com::FWResult for details.
1400 *
1401 * Here is the typical usage pattern:
1402 * <code>
1403
1404 HRESULT Bar::method()
1405 {
1406 // assume multi-errors are turned off here...
1407
1408 if (something)
1409 {
1410 // Turn on multi-error mode and make sure severity is preserved
1411 MultiResult rc = foo->method1();
1412
1413 // return on fatal error, but continue on warning or on success
1414 CheckComRCReturnRC (rc);
1415
1416 rc = foo->method2();
1417 // no matter what result, stack it and continue
1418
1419 // ...
1420
1421 // return the last worst result code (it will be preserved even if
1422 // foo->method2() returns S_OK.
1423 return rc;
1424 }
1425
1426 // multi-errors are turned off here again...
1427
1428 return S_OK;
1429 }
1430
1431 * </code>
1432 *
1433 *
1434 * @note This class is intended to be instantiated on the stack, therefore
1435 * You cannot create them using new(). Although it is possible to copy
1436 * instances of MultiResult or return them by value, please never do
1437 * that as it is breaks the class semantics (and will assert).
1438 */
1439 class MultiResult : public com::FWResult
1440 {
1441 public:
1442
1443 /**
1444 * @copydoc com::FWResult::FWResult().
1445 */
1446 MultiResult (HRESULT aRC = E_FAIL) : FWResult (aRC) { init(); }
1447
1448 MultiResult (const MultiResult &aThat) : FWResult (aThat)
1449 {
1450 /* We need this copy constructor only for GCC that wants to have
1451 * it in case of expressions like |MultiResult rc = E_FAIL;|. But
1452 * we assert since the optimizer should actually avoid the
1453 * temporary and call the other constructor directly instead. */
1454 AssertFailed();
1455 init();
1456 }
1457
1458 ~MultiResult();
1459
1460 MultiResult &operator= (HRESULT aRC)
1461 {
1462 com::FWResult::operator= (aRC);
1463 return *this;
1464 }
1465
1466 MultiResult &operator= (const MultiResult &aThat)
1467 {
1468 /* We need this copy constructor only for GCC that wants to have
1469 * it in case of expressions like |MultiResult rc = E_FAIL;|. But
1470 * we assert since the optimizer should actually avoid the
1471 * temporary and call the other constructor directly instead. */
1472 AssertFailed();
1473 com::FWResult::operator= (aThat);
1474 return *this;
1475 }
1476
1477 private:
1478
1479 DECLARE_CLS_NEW_DELETE_NOOP (MultiResult)
1480
1481 void init();
1482
1483 static RTTLS sCounter;
1484
1485 friend class VirtualBoxSupportErrorInfoImplBase;
1486 };
1487
1488 static HRESULT setError (HRESULT aResultCode, const GUID &aIID,
1489 const Bstr &aComponent,
1490 const Bstr &aText,
1491 bool aLogIt = true)
1492 {
1493 return setErrorInternal (aResultCode, aIID, aComponent, aText,
1494 false /* aWarning */, aLogIt);
1495 }
1496
1497 static HRESULT setWarning (HRESULT aResultCode, const GUID &aIID,
1498 const Bstr &aComponent,
1499 const Bstr &aText)
1500 {
1501 return setErrorInternal (aResultCode, aIID, aComponent, aText,
1502 true /* aWarning */, true /* aLogIt */);
1503 }
1504
1505 static HRESULT setError (HRESULT aResultCode, const GUID &aIID,
1506 const Bstr &aComponent,
1507 const char *aText, va_list aArgs, bool aLogIt = true)
1508 {
1509 return setErrorInternal (aResultCode, aIID, aComponent,
1510 Utf8StrFmtVA (aText, aArgs),
1511 false /* aWarning */, aLogIt);
1512 }
1513
1514 static HRESULT setWarning (HRESULT aResultCode, const GUID &aIID,
1515 const Bstr &aComponent,
1516 const char *aText, va_list aArgs)
1517 {
1518 return setErrorInternal (aResultCode, aIID, aComponent,
1519 Utf8StrFmtVA (aText, aArgs),
1520 true /* aWarning */, true /* aLogIt */);
1521 }
1522};
1523
1524/**
1525 * This template implements ISupportErrorInfo for the given component class
1526 * and provides the #setError() method to conveniently set the error information
1527 * from within interface methods' implementations.
1528 *
1529 * On Windows, the template argument must define a COM interface map using
1530 * BEGIN_COM_MAP / END_COM_MAP macros and this map must contain a
1531 * COM_INTERFACE_ENTRY(ISupportErrorInfo) definition. All interface entries
1532 * that follow it will be considered to support IErrorInfo, i.e. the
1533 * InterfaceSupportsErrorInfo() implementation will return S_OK for the
1534 * corresponding IID.
1535 *
1536 * On all platforms, the template argument must also define the following
1537 * method: |public static const wchar_t *C::getComponentName()|. See
1538 * #setError (HRESULT, const char *, ...) for a description on how it is
1539 * used.
1540 *
1541 * @param C
1542 * component class that implements one or more COM interfaces
1543 * @param I
1544 * default interface for the component. This interface's IID is used
1545 * by the shortest form of #setError, for convenience.
1546 */
1547/// @todo switch to com::SupportErrorInfo* and remove
1548template <class C, class I>
1549class ATL_NO_VTABLE VirtualBoxSupportErrorInfoImpl
1550 : protected VirtualBoxSupportErrorInfoImplBase
1551#if !defined (VBOX_WITH_XPCOM)
1552 , public ISupportErrorInfo
1553#else
1554#endif
1555{
1556public:
1557
1558#if !defined (VBOX_WITH_XPCOM)
1559 STDMETHOD(InterfaceSupportsErrorInfo) (REFIID riid)
1560 {
1561 const _ATL_INTMAP_ENTRY* pEntries = C::_GetEntries();
1562 Assert (pEntries);
1563 if (!pEntries)
1564 return S_FALSE;
1565
1566 BOOL bSupports = FALSE;
1567 BOOL bISupportErrorInfoFound = FALSE;
1568
1569 while (pEntries->pFunc != NULL && !bSupports)
1570 {
1571 if (!bISupportErrorInfoFound)
1572 {
1573 // skip the com map entries until ISupportErrorInfo is found
1574 bISupportErrorInfoFound =
1575 InlineIsEqualGUID (*(pEntries->piid), IID_ISupportErrorInfo);
1576 }
1577 else
1578 {
1579 // look for the requested interface in the rest of the com map
1580 bSupports = InlineIsEqualGUID (*(pEntries->piid), riid);
1581 }
1582 pEntries++;
1583 }
1584
1585 Assert (bISupportErrorInfoFound);
1586
1587 return bSupports ? S_OK : S_FALSE;
1588 }
1589#endif // !defined (VBOX_WITH_XPCOM)
1590
1591protected:
1592
1593 /**
1594 * Sets the error information for the current thread.
1595 * This information can be retrieved by a caller of an interface method
1596 * using IErrorInfo on Windows or nsIException on Linux, or the cross-platform
1597 * IVirtualBoxErrorInfo interface that provides extended error info (only
1598 * for components from the VirtualBox COM library). Alternatively, the
1599 * platform-independent class com::ErrorInfo (defined in VBox[XP]COM.lib)
1600 * can be used to retrieve error info in a convenient way.
1601 *
1602 * It is assumed that the interface method that uses this function returns
1603 * an unsuccessful result code to the caller (otherwise, there is no reason
1604 * for the caller to try to retrieve error info after method invocation).
1605 *
1606 * Here is a table of correspondence between this method's arguments
1607 * and IErrorInfo/nsIException/IVirtualBoxErrorInfo attributes/methods:
1608 *
1609 * argument IErrorInfo nsIException IVirtualBoxErrorInfo
1610 * ----------------------------------------------------------------
1611 * resultCode -- result resultCode
1612 * iid GetGUID -- interfaceID
1613 * component GetSource -- component
1614 * text GetDescription message text
1615 *
1616 * This method is rarely needs to be used though. There are more convenient
1617 * overloaded versions, that automatically substitute some arguments
1618 * taking their values from the template parameters. See
1619 * #setError (HRESULT, const char *, ...) for an example.
1620 *
1621 * @param aResultCode result (error) code, must not be S_OK
1622 * @param aIID IID of the interface that defines the error
1623 * @param aComponent name of the component that generates the error
1624 * @param aText error message (must not be null), an RTStrPrintf-like
1625 * format string in UTF-8 encoding
1626 * @param ... list of arguments for the format string
1627 *
1628 * @return
1629 * the error argument, for convenience, If an error occurs while
1630 * creating error info itself, that error is returned instead of the
1631 * error argument.
1632 */
1633 static HRESULT setError (HRESULT aResultCode, const GUID &aIID,
1634 const wchar_t *aComponent,
1635 const char *aText, ...)
1636 {
1637 va_list args;
1638 va_start (args, aText);
1639 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
1640 (aResultCode, aIID, aComponent, aText, args, true /* aLogIt */);
1641 va_end (args);
1642 return rc;
1643 }
1644
1645 /**
1646 * This method is the same as #setError() except that it makes sure @a
1647 * aResultCode doesn't have the error severity bit (31) set when passed
1648 * down to the created IVirtualBoxErrorInfo object.
1649 *
1650 * The error severity bit is always cleared by this call, thereof you can
1651 * use ordinary E_XXX result code constants, for convenience. However, this
1652 * behavior may be non-standard on some COM platforms.
1653 */
1654 static HRESULT setWarning (HRESULT aResultCode, const GUID &aIID,
1655 const wchar_t *aComponent,
1656 const char *aText, ...)
1657 {
1658 va_list args;
1659 va_start (args, aText);
1660 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning
1661 (aResultCode, aIID, aComponent, aText, args);
1662 va_end (args);
1663 return rc;
1664 }
1665
1666 /**
1667 * Sets the error information for the current thread.
1668 * A convenience method that automatically sets the default interface
1669 * ID (taken from the I template argument) and the component name
1670 * (a value of C::getComponentName()).
1671 *
1672 * See #setError (HRESULT, const GUID &, const wchar_t *, const char *text, ...)
1673 * for details.
1674 *
1675 * This method is the most common (and convenient) way to set error
1676 * information from within interface methods. A typical pattern of usage
1677 * is looks like this:
1678 *
1679 * <code>
1680 * return setError (E_FAIL, "Terrible Error");
1681 * </code>
1682 * or
1683 * <code>
1684 * HRESULT rc = setError (E_FAIL, "Terrible Error");
1685 * ...
1686 * return rc;
1687 * </code>
1688 */
1689 static HRESULT setError (HRESULT aResultCode, const char *aText, ...)
1690 {
1691 va_list args;
1692 va_start (args, aText);
1693 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
1694 (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, args, true /* aLogIt */);
1695 va_end (args);
1696 return rc;
1697 }
1698
1699 /**
1700 * This method is the same as #setError() except that it makes sure @a
1701 * aResultCode doesn't have the error severity bit (31) set when passed
1702 * down to the created IVirtualBoxErrorInfo object.
1703 *
1704 * The error severity bit is always cleared by this call, thereof you can
1705 * use ordinary E_XXX result code constants, for convenience. However, this
1706 * behavior may be non-standard on some COM platforms.
1707 */
1708 static HRESULT setWarning (HRESULT aResultCode, const char *aText, ...)
1709 {
1710 va_list args;
1711 va_start (args, aText);
1712 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning
1713 (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, args);
1714 va_end (args);
1715 return rc;
1716 }
1717
1718 /**
1719 * Sets the error information for the current thread, va_list variant.
1720 * A convenience method that automatically sets the default interface
1721 * ID (taken from the I template argument) and the component name
1722 * (a value of C::getComponentName()).
1723 *
1724 * See #setError (HRESULT, const GUID &, const wchar_t *, const char *text, ...)
1725 * and #setError (HRESULT, const char *, ...) for details.
1726 */
1727 static HRESULT setErrorV (HRESULT aResultCode, const char *aText,
1728 va_list aArgs)
1729 {
1730 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
1731 (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, aArgs, true /* aLogIt */);
1732 return rc;
1733 }
1734
1735 /**
1736 * This method is the same as #setErrorV() except that it makes sure @a
1737 * aResultCode doesn't have the error severity bit (31) set when passed
1738 * down to the created IVirtualBoxErrorInfo object.
1739 *
1740 * The error severity bit is always cleared by this call, thereof you can
1741 * use ordinary E_XXX result code constants, for convenience. However, this
1742 * behavior may be non-standard on some COM platforms.
1743 */
1744 static HRESULT setWarningV (HRESULT aResultCode, const char *aText,
1745 va_list aArgs)
1746 {
1747 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning
1748 (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, aArgs);
1749 return rc;
1750 }
1751
1752 /**
1753 * Sets the error information for the current thread, BStr variant.
1754 * A convenience method that automatically sets the default interface
1755 * ID (taken from the I template argument) and the component name
1756 * (a value of C::getComponentName()).
1757 *
1758 * This method is preferred if you have a ready (translated and formatted)
1759 * Bstr string, because it omits an extra conversion Utf8Str -> Bstr.
1760 *
1761 * See #setError (HRESULT, const GUID &, const wchar_t *, const char *text, ...)
1762 * and #setError (HRESULT, const char *, ...) for details.
1763 */
1764 static HRESULT setErrorBstr (HRESULT aResultCode, const Bstr &aText)
1765 {
1766 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
1767 (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, true /* aLogIt */);
1768 return rc;
1769 }
1770
1771 /**
1772 * This method is the same as #setErrorBstr() except that it makes sure @a
1773 * aResultCode doesn't have the error severity bit (31) set when passed
1774 * down to the created IVirtualBoxErrorInfo object.
1775 *
1776 * The error severity bit is always cleared by this call, thereof you can
1777 * use ordinary E_XXX result code constants, for convenience. However, this
1778 * behavior may be non-standard on some COM platforms.
1779 */
1780 static HRESULT setWarningBstr (HRESULT aResultCode, const Bstr &aText)
1781 {
1782 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning
1783 (aResultCode, COM_IIDOF(I), C::getComponentName(), aText);
1784 return rc;
1785 }
1786
1787 /**
1788 * Sets the error information for the current thread.
1789 * A convenience method that automatically sets the component name
1790 * (a value of C::getComponentName()), but allows to specify the interface
1791 * id manually.
1792 *
1793 * See #setError (HRESULT, const GUID &, const wchar_t *, const char *text, ...)
1794 * for details.
1795 */
1796 static HRESULT setError (HRESULT aResultCode, const GUID &aIID,
1797 const char *aText, ...)
1798 {
1799 va_list args;
1800 va_start (args, aText);
1801 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
1802 (aResultCode, aIID, C::getComponentName(), aText, args, true /* aLogIt */);
1803 va_end (args);
1804 return rc;
1805 }
1806
1807 /**
1808 * This method is the same as #setError() except that it makes sure @a
1809 * aResultCode doesn't have the error severity bit (31) set when passed
1810 * down to the created IVirtualBoxErrorInfo object.
1811 *
1812 * The error severity bit is always cleared by this call, thereof you can
1813 * use ordinary E_XXX result code constants, for convenience. However, this
1814 * behavior may be non-standard on some COM platforms.
1815 */
1816 static HRESULT setWarning (HRESULT aResultCode, const GUID &aIID,
1817 const char *aText, ...)
1818 {
1819 va_list args;
1820 va_start (args, aText);
1821 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning
1822 (aResultCode, aIID, C::getComponentName(), aText, args);
1823 va_end (args);
1824 return rc;
1825 }
1826
1827 /**
1828 * Sets the error information for the current thread but doesn't put
1829 * anything in the release log. This is very useful for avoiding
1830 * harmless error from causing confusion.
1831 *
1832 * It is otherwise identical to #setError (HRESULT, const char *text, ...).
1833 */
1834 static HRESULT setErrorNoLog (HRESULT aResultCode, const char *aText, ...)
1835 {
1836 va_list args;
1837 va_start (args, aText);
1838 HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
1839 (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, args, false /* aLogIt */);
1840 va_end (args);
1841 return rc;
1842 }
1843
1844private:
1845
1846};
1847
1848////////////////////////////////////////////////////////////////////////////////
1849
1850/**
1851 * Base class to track VirtualBoxBase children of the component.
1852 *
1853 * This class is a preferable VirtualBoxBase replacement for components
1854 * that operate with collections of child components. It gives two useful
1855 * possibilities:
1856 *
1857 * <ol><li>
1858 * Given an IUnknown instance, it's possible to quickly determine
1859 * whether this instance represents a child object created by the given
1860 * component, and if so, get a valid VirtualBoxBase pointer to the child
1861 * object. The returned pointer can be then safely casted to the
1862 * actual class of the child object (to get access to its "internal"
1863 * non-interface methods) provided that no other child components implement
1864 * the same initial interface IUnknown is queried from.
1865 * </li><li>
1866 * When the parent object uninitializes itself, it can easily unintialize
1867 * all its VirtualBoxBase derived children (using their
1868 * VirtualBoxBase::uninit() implementations). This is done simply by
1869 * calling the #uninitDependentChildren() method.
1870 * </li></ol>
1871 *
1872 * In order to let the above work, the following must be done:
1873 * <ol><li>
1874 * When a child object is initialized, it calls #addDependentChild() of
1875 * its parent to register itself within the list of dependent children.
1876 * </li><li>
1877 * When a child object it is uninitialized, it calls #removeDependentChild()
1878 * to unregister itself. This must be done <b>after</b> the child has called
1879 * setReady(false) to indicate it is no more valid, and <b>not</b> from under
1880 * the child object's lock. Note also, that the first action the child's
1881 * uninit() implementation must do is to check for readiness after acquiring
1882 * the object's lock and return immediately if not ready.
1883 * </li></ol>
1884 *
1885 * Children added by #addDependentChild() are <b>weakly</b> referenced
1886 * (i.e. AddRef() is not called), so when a child is externally destructed
1887 * (i.e. its reference count goes to zero), it will automatically remove
1888 * itself from a map of dependent children, provided that it follows the
1889 * rules described here.
1890 *
1891 * @note
1892 * Because of weak referencing, deadlocks and assertions are very likely
1893 * if #addDependentChild() or #removeDependentChild() are used incorrectly
1894 * (called at inappropriate times). Check the above rules once more.
1895 *
1896 * @deprecated Use VirtualBoxBaseWithChildrenNEXT for new classes.
1897 */
1898class VirtualBoxBaseWithChildren : public VirtualBoxBase
1899{
1900public:
1901
1902 VirtualBoxBaseWithChildren()
1903 : mUninitDoneSem (NIL_RTSEMEVENT), mChildrenLeft (0)
1904 {}
1905
1906 virtual ~VirtualBoxBaseWithChildren()
1907 {}
1908
1909 /**
1910 * Adds the given child to the map of dependent children.
1911 * Intended to be called from the child's init() method,
1912 * from under the child's lock.
1913 *
1914 * @param C the child object to add (must inherit VirtualBoxBase AND
1915 * implement some interface)
1916 */
1917 template <class C>
1918 void addDependentChild (C *child)
1919 {
1920 AssertReturn (child, (void) 0);
1921 addDependentChild (child, child);
1922 }
1923
1924 /**
1925 * Removes the given child from the map of dependent children.
1926 * Must be called <b>after<b> the child has called setReady(false), and
1927 * <b>not</b> from under the child object's lock.
1928 *
1929 * @param C the child object to remove (must inherit VirtualBoxBase AND
1930 * implement some interface)
1931 */
1932 template <class C>
1933 void removeDependentChild (C *child)
1934 {
1935 AssertReturn (child, (void) 0);
1936 /// @todo (r=dmik) the below check (and the relevant comment above)
1937 // seems to be not necessary any more once we completely switch to
1938 // the NEXT locking scheme. This requires altering removeDependentChild()
1939 // and uninitDependentChildren() as well (due to the new state scheme,
1940 // there is a separate mutex for state transition, so calling the
1941 // child's uninit() from under the children map lock should not produce
1942 // dead-locks any more).
1943 Assert (!child->isWriteLockOnCurrentThread() || child->lockHandle() == lockHandle());
1944 removeDependentChild (ComPtr<IUnknown> (child));
1945 }
1946
1947protected:
1948
1949 void uninitDependentChildren();
1950
1951 VirtualBoxBase *getDependentChild (const ComPtr<IUnknown> &unk);
1952
1953private:
1954
1955 void addDependentChild (const ComPtr<IUnknown> &unk, VirtualBoxBase *child);
1956 void removeDependentChild (const ComPtr<IUnknown> &unk);
1957
1958 typedef std::map <IUnknown *, VirtualBoxBase *> DependentChildren;
1959 DependentChildren mDependentChildren;
1960
1961 WriteLockHandle mMapLock;
1962
1963 RTSEMEVENT mUninitDoneSem;
1964 unsigned mChildrenLeft;
1965};
1966
1967////////////////////////////////////////////////////////////////////////////////
1968
1969/**
1970 * Base class to track VirtualBoxBaseNEXT chlidren of the component.
1971 *
1972 * This class is a preferrable VirtualBoxBase replacement for components that
1973 * operate with collections of child components. It gives two useful
1974 * possibilities:
1975 *
1976 * <ol><li>
1977 * Given an IUnknown instance, it's possible to quickly determine
1978 * whether this instance represents a child object that belongs to the
1979 * given component, and if so, get a valid VirtualBoxBase pointer to the
1980 * child object. The returned pointer can be then safely casted to the
1981 * actual class of the child object (to get access to its "internal"
1982 * non-interface methods) provided that no other child components implement
1983 * the same original COM interface IUnknown is queried from.
1984 * </li><li>
1985 * When the parent object uninitializes itself, it can easily unintialize
1986 * all its VirtualBoxBase derived children (using their
1987 * VirtualBoxBase::uninit() implementations). This is done simply by
1988 * calling the #uninitDependentChildren() method.
1989 * </li></ol>
1990 *
1991 * In order to let the above work, the following must be done:
1992 * <ol><li>
1993 * When a child object is initialized, it calls #addDependentChild() of
1994 * its parent to register itself within the list of dependent children.
1995 * </li><li>
1996 * When the child object it is uninitialized, it calls
1997 * #removeDependentChild() to unregister itself.
1998 * </li></ol>
1999 *
2000 * Note that if the parent object does not call #uninitDependentChildren() when
2001 * it gets uninitialized, it must call uninit() methods of individual children
2002 * manually to disconnect them; a failure to do so will cause crashes in these
2003 * methods when children get destroyed. The same applies to children not calling
2004 * #removeDependentChild() when getting destroyed.
2005 *
2006 * Note that children added by #addDependentChild() are <b>weakly</b> referenced
2007 * (i.e. AddRef() is not called), so when a child object is deleted externally
2008 * (because it's reference count goes to zero), it will automatically remove
2009 * itself from the map of dependent children provided that it follows the rules
2010 * described here.
2011 *
2012 * Access to the child list is serialized using the #childrenLock() lock handle
2013 * (which defaults to the general object lock handle (see
2014 * VirtualBoxBase::lockHandle()). This lock is used by all add/remove methods of
2015 * this class so be aware of the need to preserve the {parent, child} lock order
2016 * when calling these methods.
2017 *
2018 * Read individual method descriptions to get further information.
2019 *
2020 * @todo This is a VirtualBoxBaseWithChildren equivalent that uses the
2021 * VirtualBoxBaseNEXT implementation. Will completely supersede
2022 * VirtualBoxBaseWithChildren after the old VirtualBoxBase implementation
2023 * has gone.
2024 */
2025class VirtualBoxBaseWithChildrenNEXT : public VirtualBoxBase
2026{
2027public:
2028
2029 VirtualBoxBaseWithChildrenNEXT()
2030 {}
2031
2032 virtual ~VirtualBoxBaseWithChildrenNEXT()
2033 {}
2034
2035 /**
2036 * Lock handle to use when adding/removing child objects from the list of
2037 * children. It is guaranteed that no any other lock is requested in methods
2038 * of this class while holding this lock.
2039 *
2040 * @warning By default, this simply returns the general object's lock handle
2041 * (see VirtualBoxBase::lockHandle()) which is sufficient for most
2042 * cases.
2043 */
2044 virtual RWLockHandle *childrenLock() { return lockHandle(); }
2045
2046 /**
2047 * Adds the given child to the list of dependent children.
2048 *
2049 * Usually gets called from the child's init() method.
2050 *
2051 * @note @a aChild (unless it is in InInit state) must be protected by
2052 * VirtualBoxBase::AutoCaller to make sure it is not uninitialized on
2053 * another thread during this method's call.
2054 *
2055 * @note When #childrenLock() is not overloaded (returns the general object
2056 * lock) and this method is called from under the child's read or
2057 * write lock, make sure the {parent, child} locking order is
2058 * preserved by locking the callee (this object) for writing before
2059 * the child's lock.
2060 *
2061 * @param aChild Child object to add (must inherit VirtualBoxBase AND
2062 * implement some interface).
2063 *
2064 * @note Locks #childrenLock() for writing.
2065 */
2066 template <class C>
2067 void addDependentChild (C *aChild)
2068 {
2069 AssertReturnVoid (aChild != NULL);
2070 doAddDependentChild (ComPtr<IUnknown> (aChild), aChild);
2071 }
2072
2073 /**
2074 * Equivalent to template <class C> void addDependentChild (C *aChild)
2075 * but takes a ComObjPtr<C> argument.
2076 */
2077 template <class C>
2078 void addDependentChild (const ComObjPtr<C> &aChild)
2079 {
2080 AssertReturnVoid (!aChild.isNull());
2081 doAddDependentChild (ComPtr<IUnknown> (static_cast <C *> (aChild)), aChild);
2082 }
2083
2084 /**
2085 * Removes the given child from the list of dependent children.
2086 *
2087 * Usually gets called from the child's uninit() method.
2088 *
2089 * Keep in mind that the called (parent) object may be no longer available
2090 * (i.e. may be deleted deleted) after this method returns, so you must not
2091 * call any other parent's methods after that!
2092 *
2093 * @note Locks #childrenLock() for writing.
2094 *
2095 * @note @a aChild (unless it is in InUninit state) must be protected by
2096 * VirtualBoxBase::AutoCaller to make sure it is not uninitialized on
2097 * another thread during this method's call.
2098 *
2099 * @note When #childrenLock() is not overloaded (returns the general object
2100 * lock) and this method is called from under the child's read or
2101 * write lock, make sure the {parent, child} locking order is
2102 * preserved by locking the callee (this object) for writing before
2103 * the child's lock. This is irrelevant when the method is called from
2104 * under this object's VirtualBoxBaseProto::AutoUninitSpan (i.e. in
2105 * InUninit state) since in this case no locking is done.
2106 *
2107 * @param aChild Child object to remove.
2108 *
2109 * @note Locks #childrenLock() for writing.
2110 */
2111 template <class C>
2112 void removeDependentChild (C *aChild)
2113 {
2114 AssertReturnVoid (aChild != NULL);
2115 doRemoveDependentChild (ComPtr<IUnknown> (aChild));
2116 }
2117
2118 /**
2119 * Equivalent to template <class C> void removeDependentChild (C *aChild)
2120 * but takes a ComObjPtr<C> argument.
2121 */
2122 template <class C>
2123 void removeDependentChild (const ComObjPtr<C> &aChild)
2124 {
2125 AssertReturnVoid (!aChild.isNull());
2126 doRemoveDependentChild (ComPtr<IUnknown> (static_cast <C *> (aChild)));
2127 }
2128
2129protected:
2130
2131 void uninitDependentChildren();
2132
2133 VirtualBoxBase *getDependentChild(const ComPtr<IUnknown> &aUnk);
2134
2135private:
2136 void doAddDependentChild(IUnknown *aUnk, VirtualBoxBase *aChild);
2137 void doRemoveDependentChild (IUnknown *aUnk);
2138
2139 typedef std::map<IUnknown*, VirtualBoxBase*> DependentChildren;
2140 DependentChildren mDependentChildren;
2141};
2142
2143////////////////////////////////////////////////////////////////////////////////
2144
2145////////////////////////////////////////////////////////////////////////////////
2146
2147/**
2148 * Base class to track component's children of the particular type.
2149 *
2150 * This class is similar to VirtualBoxBaseWithChildrenNEXT with the exception
2151 * that all children must be of the same type. For this reason, it's not
2152 * necessary to use a map to store children -- a list is used instead.
2153 *
2154 * Also, as opposed to VirtualBoxBaseWithChildren, children added by
2155 * #addDependentChild() are <b>strongly</b> referenced, so that they cannot be
2156 * deleted (even by a third party) until #removeDependentChild() is called on
2157 * them. This also means that a failure to call #removeDependentChild() and
2158 * #uninitDependentChildren() at appropriate times as described in
2159 * VirtualBoxBaseWithChildrenNEXT may cause stuck references that won't be able
2160 * uninitialize themselves.
2161 *
2162 * See individual method descriptions for further information.
2163 *
2164 * @param C Type of child objects (must inherit VirtualBoxBase AND implement
2165 * some interface).
2166 *
2167 * @todo This is a VirtualBoxBaseWithChildren equivalent that uses the
2168 * VirtualBoxBaseNEXT implementation. Will completely supersede
2169 * VirtualBoxBaseWithChildren after the old VirtualBoxBase implementation
2170 * has gone.
2171 */
2172template <class C>
2173class VirtualBoxBaseWithTypedChildren : public VirtualBoxBase
2174{
2175public:
2176
2177 typedef std::list <ComObjPtr<C> > DependentChildren;
2178
2179 VirtualBoxBaseWithTypedChildren()
2180 {}
2181
2182 virtual ~VirtualBoxBaseWithTypedChildren()
2183 {}
2184
2185 /**
2186 * Lock handle to use when adding/removing child objects from the list of
2187 * children. It is guaranteed that no any other lock is requested in methods
2188 * of this class while holding this lock.
2189 *
2190 * @warning By default, this simply returns the general object's lock handle
2191 * (see VirtualBoxBase::lockHandle()) which is sufficient for most
2192 * cases.
2193 */
2194 virtual RWLockHandle *childrenLock() { return lockHandle(); }
2195
2196 /**
2197 * Adds the given child to the list of dependent children.
2198 *
2199 * Usually gets called from the child's init() method.
2200 *
2201 * @note @a aChild (unless it is in InInit state) must be protected by
2202 * VirtualBoxBase::AutoCaller to make sure it is not uninitialized on
2203 * another thread during this method's call.
2204 *
2205 * @note When #childrenLock() is not overloaded (returns the general object
2206 * lock) and this method is called from under the child's read or
2207 * write lock, make sure the {parent, child} locking order is
2208 * preserved by locking the callee (this object) for writing before
2209 * the child's lock.
2210 *
2211 * @param aChild Child object to add.
2212 *
2213 * @note Locks #childrenLock() for writing.
2214 */
2215 void addDependentChild (C *aChild)
2216 {
2217 AssertReturnVoid (aChild != NULL);
2218
2219 AutoCaller autoCaller (this);
2220
2221 /* sanity */
2222 AssertReturnVoid (autoCaller.state() == InInit ||
2223 autoCaller.state() == Ready ||
2224 autoCaller.state() == Limited);
2225
2226 AutoWriteLock chLock (childrenLock());
2227 mDependentChildren.push_back (aChild);
2228 }
2229
2230 /**
2231 * Removes the given child from the list of dependent children.
2232 *
2233 * Usually gets called from the child's uninit() method.
2234 *
2235 * Keep in mind that the called (parent) object may be no longer available
2236 * (i.e. may be deleted deleted) after this method returns, so you must not
2237 * call any other parent's methods after that!
2238 *
2239 * @note @a aChild (unless it is in InUninit state) must be protected by
2240 * VirtualBoxBase::AutoCaller to make sure it is not uninitialized on
2241 * another thread during this method's call.
2242 *
2243 * @note When #childrenLock() is not overloaded (returns the general object
2244 * lock) and this method is called from under the child's read or
2245 * write lock, make sure the {parent, child} locking order is
2246 * preserved by locking the callee (this object) for writing before
2247 * the child's lock. This is irrelevant when the method is called from
2248 * under this object's AutoUninitSpan (i.e. in InUninit state) since
2249 * in this case no locking is done.
2250 *
2251 * @param aChild Child object to remove.
2252 *
2253 * @note Locks #childrenLock() for writing.
2254 */
2255 void removeDependentChild (C *aChild)
2256 {
2257 AssertReturnVoid (aChild);
2258
2259 AutoCaller autoCaller (this);
2260
2261 /* sanity */
2262 AssertReturnVoid (autoCaller.state() == InUninit ||
2263 autoCaller.state() == InInit ||
2264 autoCaller.state() == Ready ||
2265 autoCaller.state() == Limited);
2266
2267 /* return shortly; we are strongly referenced so the object won't get
2268 * deleted if it calls init() before uninitDependentChildren() does
2269 * and therefore the list will still contain a valid reference that will
2270 * be correctly processed by uninitDependentChildren() anyway */
2271 if (autoCaller.state() == InUninit)
2272 return;
2273
2274 AutoWriteLock chLock (childrenLock());
2275 mDependentChildren.remove (aChild);
2276 }
2277
2278protected:
2279
2280 /**
2281 * Returns the read-only list of all dependent children.
2282 *
2283 * @note Access the returned list (iterate, get size etc.) only after making
2284 * sure #childrenLock() is locked for reading or for writing!
2285 */
2286 const DependentChildren &dependentChildren() const { return mDependentChildren; }
2287
2288 /**
2289 * Uninitializes all dependent children registered on this object with
2290 * #addDependentChild().
2291 *
2292 * Must be called from within the VirtualBoxBaseProto::AutoUninitSpan (i.e.
2293 * typically from this object's uninit() method) to uninitialize children
2294 * before this object goes out of service and becomes unusable.
2295 *
2296 * Note that this method will call uninit() methods of child objects. If
2297 * these methods need to call the parent object during uninitialization,
2298 * #uninitDependentChildren() must be called before the relevant part of the
2299 * parent is uninitialized: usually at the beginning of the parent
2300 * uninitialization sequence.
2301 *
2302 * @note May lock something through the called children.
2303 */
2304 void uninitDependentChildren()
2305 {
2306 AutoCaller autoCaller (this);
2307
2308 /* We don't want to hold the childrenLock() write lock here (necessary
2309 * to protect mDependentChildren) when uninitializing children because
2310 * we want to avoid a possible deadlock where we could get stuck in
2311 * child->uninit() blocked by AutoUninitSpan waiting for the number of
2312 * child's callers to drop to zero (or for another AutoUninitSpan to
2313 * finish), while some other thread is stuck in our
2314 * removeDependentChild() method called for that child and waiting for
2315 * the childrenLock()'s write lock.
2316 *
2317 * The only safe place to not lock and keep accessing our data members
2318 * is the InUninit state (no active call to our object may exist on
2319 * another thread when we are in InUinint, provided that all such calls
2320 * use the AutoCaller class of course). InUinint is also used as a flag
2321 * by removeDependentChild() that prevents touching mDependentChildren
2322 * from outside. Therefore, we assert. Note that InInit is also fine
2323 * since no any object may access us by that time.
2324 */
2325 AssertReturnVoid (autoCaller.state() == InUninit ||
2326 autoCaller.state() == InInit);
2327
2328 if (mDependentChildren.size())
2329 {
2330 for (typename DependentChildren::iterator it = mDependentChildren.begin();
2331 it != mDependentChildren.end(); ++ it)
2332 {
2333 C *child = (*it);
2334 Assert (child);
2335
2336 /* Note that if child->uninit() happens to be called on another
2337 * thread right before us and is not yet finished, the second
2338 * uninit() call will wait until the first one has done so
2339 * (thanks to AutoUninitSpan). */
2340 if (child)
2341 child->uninit();
2342 }
2343
2344 /* release all strong references we hold */
2345 mDependentChildren.clear();
2346 }
2347 }
2348
2349 /**
2350 * Removes (detaches) all dependent children registered with
2351 * #addDependentChild(), without uninitializing them.
2352 *
2353 * @note @a |this| (unless it is in InUninit state) must be protected by
2354 * VirtualBoxBase::AutoCaller to make sure it is not uninitialized on
2355 * another thread during this method's call.
2356 *
2357 * @note Locks #childrenLock() for writing.
2358 */
2359 void removeDependentChildren()
2360 {
2361 AutoWriteLock chLock (childrenLock());
2362 mDependentChildren.clear();
2363 }
2364
2365private:
2366
2367 DependentChildren mDependentChildren;
2368};
2369
2370////////////////////////////////////////////////////////////////////////////////
2371
2372/// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely
2373/**
2374 * Simple template that manages data structure allocation/deallocation
2375 * and supports data pointer sharing (the instance that shares the pointer is
2376 * not responsible for memory deallocation as opposed to the instance that
2377 * owns it).
2378 */
2379template <class D>
2380class Shareable
2381{
2382public:
2383
2384 Shareable() : mData (NULL), mIsShared (FALSE) {}
2385 ~Shareable() { free(); }
2386
2387 void allocate() { attach (new D); }
2388
2389 virtual void free() {
2390 if (mData) {
2391 if (!mIsShared)
2392 delete mData;
2393 mData = NULL;
2394 mIsShared = false;
2395 }
2396 }
2397
2398 void attach (D *data) {
2399 AssertMsg (data, ("new data must not be NULL"));
2400 if (data && mData != data) {
2401 if (mData && !mIsShared)
2402 delete mData;
2403 mData = data;
2404 mIsShared = false;
2405 }
2406 }
2407
2408 void attach (Shareable &data) {
2409 AssertMsg (
2410 data.mData == mData || !data.mIsShared,
2411 ("new data must not be shared")
2412 );
2413 if (this != &data && !data.mIsShared) {
2414 attach (data.mData);
2415 data.mIsShared = true;
2416 }
2417 }
2418
2419 void share (D *data) {
2420 AssertMsg (data, ("new data must not be NULL"));
2421 if (mData != data) {
2422 if (mData && !mIsShared)
2423 delete mData;
2424 mData = data;
2425 mIsShared = true;
2426 }
2427 }
2428
2429 void share (const Shareable &data) { share (data.mData); }
2430
2431 void attachCopy (const D *data) {
2432 AssertMsg (data, ("data to copy must not be NULL"));
2433 if (data)
2434 attach (new D (*data));
2435 }
2436
2437 void attachCopy (const Shareable &data) {
2438 attachCopy (data.mData);
2439 }
2440
2441 virtual D *detach() {
2442 D *d = mData;
2443 mData = NULL;
2444 mIsShared = false;
2445 return d;
2446 }
2447
2448 D *data() const {
2449 return mData;
2450 }
2451
2452 D *operator->() const {
2453 AssertMsg (mData, ("data must not be NULL"));
2454 return mData;
2455 }
2456
2457 bool isNull() const { return mData == NULL; }
2458 bool operator!() const { return isNull(); }
2459
2460 bool isShared() const { return mIsShared; }
2461
2462protected:
2463
2464 D *mData;
2465 bool mIsShared;
2466};
2467
2468/// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely
2469/**
2470 * Simple template that enhances Shareable<> and supports data
2471 * backup/rollback/commit (using the copy constructor of the managed data
2472 * structure).
2473 */
2474template <class D>
2475class Backupable : public Shareable <D>
2476{
2477public:
2478
2479 Backupable() : Shareable <D> (), mBackupData (NULL) {}
2480
2481 void free()
2482 {
2483 AssertMsg (this->mData || !mBackupData, ("backup must be NULL if data is NULL"));
2484 rollback();
2485 Shareable <D>::free();
2486 }
2487
2488 D *detach()
2489 {
2490 AssertMsg (this->mData || !mBackupData, ("backup must be NULL if data is NULL"));
2491 rollback();
2492 return Shareable <D>::detach();
2493 }
2494
2495 void share (const Backupable &data)
2496 {
2497 AssertMsg (!data.isBackedUp(), ("data to share must not be backed up"));
2498 if (!data.isBackedUp())
2499 Shareable <D>::share (data.mData);
2500 }
2501
2502 /**
2503 * Stores the current data pointer in the backup area, allocates new data
2504 * using the copy constructor on current data and makes new data active.
2505 */
2506 void backup()
2507 {
2508 AssertMsg (this->mData, ("data must not be NULL"));
2509 if (this->mData && !mBackupData)
2510 {
2511 mBackupData = this->mData;
2512 this->mData = new D (*mBackupData);
2513 }
2514 }
2515
2516 /**
2517 * Deletes new data created by #backup() and restores previous data pointer
2518 * stored in the backup area, making it active again.
2519 */
2520 void rollback()
2521 {
2522 if (this->mData && mBackupData)
2523 {
2524 delete this->mData;
2525 this->mData = mBackupData;
2526 mBackupData = NULL;
2527 }
2528 }
2529
2530 /**
2531 * Commits current changes by deleting backed up data and clearing up the
2532 * backup area. The new data pointer created by #backup() remains active
2533 * and becomes the only managed pointer.
2534 *
2535 * This method is much faster than #commitCopy() (just a single pointer
2536 * assignment operation), but makes the previous data pointer invalid
2537 * (because it is freed). For this reason, this method must not be
2538 * used if it's possible that data managed by this instance is shared with
2539 * some other Shareable instance. See #commitCopy().
2540 */
2541 void commit()
2542 {
2543 if (this->mData && mBackupData)
2544 {
2545 if (!this->mIsShared)
2546 delete mBackupData;
2547 mBackupData = NULL;
2548 this->mIsShared = false;
2549 }
2550 }
2551
2552 /**
2553 * Commits current changes by assigning new data to the previous data
2554 * pointer stored in the backup area using the assignment operator.
2555 * New data is deleted, the backup area is cleared and the previous data
2556 * pointer becomes active and the only managed pointer.
2557 *
2558 * This method is slower than #commit(), but it keeps the previous data
2559 * pointer valid (i.e. new data is copied to the same memory location).
2560 * For that reason it's safe to use this method on instances that share
2561 * managed data with other Shareable instances.
2562 */
2563 void commitCopy()
2564 {
2565 if (this->mData && mBackupData)
2566 {
2567 *mBackupData = *(this->mData);
2568 delete this->mData;
2569 this->mData = mBackupData;
2570 mBackupData = NULL;
2571 }
2572 }
2573
2574 void assignCopy (const D *data)
2575 {
2576 AssertMsg (this->mData, ("data must not be NULL"));
2577 AssertMsg (data, ("data to copy must not be NULL"));
2578 if (this->mData && data)
2579 {
2580 if (!mBackupData)
2581 {
2582 mBackupData = this->mData;
2583 this->mData = new D (*data);
2584 }
2585 else
2586 *this->mData = *data;
2587 }
2588 }
2589
2590 void assignCopy (const Backupable &data)
2591 {
2592 assignCopy (data.mData);
2593 }
2594
2595 bool isBackedUp() const
2596 {
2597 return mBackupData != NULL;
2598 }
2599
2600 bool hasActualChanges() const
2601 {
2602 AssertMsg (this->mData, ("data must not be NULL"));
2603 return this->mData != NULL && mBackupData != NULL &&
2604 !(*this->mData == *mBackupData);
2605 }
2606
2607 D *backedUpData() const
2608 {
2609 return mBackupData;
2610 }
2611
2612protected:
2613
2614 D *mBackupData;
2615};
2616
2617#endif // ____H_VIRTUALBOXBASEIMPL
2618/* 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