VirtualBox

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

Last change on this file since 105006 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

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