VirtualBox

source: vbox/trunk/src/VBox/Main/include/ObjectState.h@ 76454

Last change on this file since 76454 was 75660, checked in by vboxsync, 6 years ago

Main/AutoCaller: add a "try lock" option to AutoUninitSpan, for situations where the uninit should fail when there are still callers active.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1/* $Id: ObjectState.h 75660 2018-11-22 12:20:52Z vboxsync $ */
2/** @file
3 *
4 * VirtualBox object state handling definitions
5 */
6
7/*
8 * Copyright (C) 2006-2017 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#ifndef ____H_OBJECTSTATE
20#define ____H_OBJECTSTATE
21
22#include "VBox/com/defs.h"
23#include "VBox/com/AutoLock.h"
24#include "VBox/com/ErrorInfo.h"
25
26// Forward declaration needed, but nothing more.
27class VirtualBoxBase;
28
29////////////////////////////////////////////////////////////////////////////////
30//
31// ObjectState
32//
33////////////////////////////////////////////////////////////////////////////////
34
35/**
36 * Thec functionality implemented by this class is the primary object state
37 * (used by VirtualBoxBase and thus part of all API classes) that indicates
38 * if the object is ready to serve the calls, and if not, what stage it is
39 * currently at. Here is the primary state diagram:
40 *
41 * +-------------------------------------------------------+
42 * | |
43 * | (InitFailed) -----------------------+ |
44 * | ^ | |
45 * v | v |
46 * [*] ---> NotReady ----> (InInit) -----> Ready -----> (InUninit) ----+
47 * ^ |
48 * | v
49 * | Limited
50 * | |
51 * +-------+
52 *
53 * The object is fully operational only when its state is Ready. The Limited
54 * state means that only some vital part of the object is operational, and it
55 * requires some sort of reinitialization to become fully operational. The
56 * NotReady state means the object is basically dead: it either was not yet
57 * initialized after creation at all, or was uninitialized and is waiting to be
58 * destroyed when the last reference to it is released. All other states are
59 * transitional.
60 *
61 * The NotReady->InInit->Ready, NotReady->InInit->Limited and
62 * NotReady->InInit->InitFailed transition is done by the AutoInitSpan smart
63 * class.
64 *
65 * The Limited->InInit->Ready, Limited->InInit->Limited and
66 * Limited->InInit->InitFailed transition is done by the AutoReinitSpan smart
67 * class.
68 *
69 * The Ready->InUninit->NotReady and InitFailed->InUninit->NotReady
70 * transitions are done by the AutoUninitSpan smart class.
71 *
72 * In order to maintain the primary state integrity and declared functionality
73 * the following rules apply everywhere:
74 *
75 * 1) Use the above Auto*Span classes to perform state transitions. See the
76 * individual class descriptions for details.
77 *
78 * 2) All public methods of subclasses (i.e. all methods that can be called
79 * directly, not only from within other methods of the subclass) must have a
80 * standard prolog as described in the AutoCaller and AutoLimitedCaller
81 * documentation. Alternatively, they must use #addCaller() and
82 * #releaseCaller() directly (and therefore have both the prolog and the
83 * epilog), but this is not recommended because it is easy to forget the
84 * matching release, e.g. returning before reaching the call.
85 */
86class ObjectState
87{
88public:
89 enum State { NotReady, Ready, InInit, InUninit, InitFailed, Limited };
90
91 ObjectState(VirtualBoxBase *aObj);
92 ~ObjectState();
93
94 State getState();
95
96 HRESULT addCaller(bool aLimited = false);
97 void releaseCaller();
98
99 bool autoInitSpanConstructor(State aExpectedState);
100 void autoInitSpanDestructor(State aNewState, HRESULT aFailedRC, com::ErrorInfo *aFailedEI);
101 State autoUninitSpanConstructor(bool fTry);
102 void autoUninitSpanDestructor();
103
104private:
105 ObjectState();
106
107 void setState(State aState);
108
109 /** Pointer to the managed object, mostly for error signalling or debugging
110 * purposes, not used much. Guaranteed to be valid during the lifetime of
111 * this object, no need to mess with refcount. */
112 VirtualBoxBase *mObj;
113 /** Primary state of this object */
114 State mState;
115 /** Thread that caused the last state change */
116 RTTHREAD mStateChangeThread;
117 /** Result code for failed object initialization */
118 HRESULT mFailedRC;
119 /** Error information for failed object initialization */
120 com::ErrorInfo *mpFailedEI;
121 /** Total number of active calls to this object */
122 unsigned mCallers;
123 /** Posted when the number of callers drops to zero */
124 RTSEMEVENT mZeroCallersSem;
125 /** Posted when the object goes from InInit/InUninit to some other state */
126 RTSEMEVENTMULTI mInitUninitSem;
127 /** Number of threads waiting for mInitUninitDoneSem */
128 unsigned mInitUninitWaiters;
129
130 /** Protects access to state related data members */
131 util::RWLockHandle mStateLock;
132
133private:
134 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(ObjectState); /* Shuts up MSC warning C4625. */
135};
136
137#endif // !____H_OBJECTSTATE
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