1 | /* $Id: AutoStateDep.h 103532 2024-02-22 14:05:31Z vboxsync $ */
|
---|
2 |
|
---|
3 | #ifndef MAIN_INCLUDED_AutoStateDep_h
|
---|
4 | #define MAIN_INCLUDED_AutoStateDep_h
|
---|
5 | #ifndef RT_WITHOUT_PRAGMA_ONCE
|
---|
6 | # pragma once
|
---|
7 | #endif
|
---|
8 |
|
---|
9 | /** @file
|
---|
10 | *
|
---|
11 | * AutoStateDep template classes, formerly in MachineImpl.h. Use these if
|
---|
12 | * you need to ensure that the machine state does not change over a certain
|
---|
13 | * period of time.
|
---|
14 | */
|
---|
15 |
|
---|
16 | /*
|
---|
17 | * Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
---|
18 | *
|
---|
19 | * This file is part of VirtualBox base platform packages, as
|
---|
20 | * available from https://www.virtualbox.org.
|
---|
21 | *
|
---|
22 | * This program is free software; you can redistribute it and/or
|
---|
23 | * modify it under the terms of the GNU General Public License
|
---|
24 | * as published by the Free Software Foundation, in version 3 of the
|
---|
25 | * License.
|
---|
26 | *
|
---|
27 | * This program is distributed in the hope that it will be useful, but
|
---|
28 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
30 | * General Public License for more details.
|
---|
31 | *
|
---|
32 | * You should have received a copy of the GNU General Public License
|
---|
33 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
34 | *
|
---|
35 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
36 | */
|
---|
37 |
|
---|
38 | /**
|
---|
39 | * Helper class that safely manages the machine state dependency by
|
---|
40 | * calling Machine::addStateDependency() on construction and
|
---|
41 | * Machine::releaseStateDependency() on destruction. Intended for Machine
|
---|
42 | * children. The usage pattern is:
|
---|
43 | *
|
---|
44 | * @code
|
---|
45 | * AutoCaller autoCaller(this);
|
---|
46 | * if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
|
---|
47 | *
|
---|
48 | * Machine::AutoStateDependency<MutableStateDep> adep(mParent);
|
---|
49 | * if (FAILED(stateDep.hrc())) return stateDep.hrc();
|
---|
50 | * ...
|
---|
51 | * // code that depends on the particular machine state
|
---|
52 | * ...
|
---|
53 | * @endcode
|
---|
54 | *
|
---|
55 | * Note that it is more convenient to use the following individual
|
---|
56 | * shortcut classes instead of using this template directly:
|
---|
57 | * AutoAnyStateDependency, AutoMutableStateDependency,
|
---|
58 | * AutoMutableOrSavedStateDependency, AutoMutableOrRunningStateDependency
|
---|
59 | * or AutoMutableOrSavedOrRunningStateDependency. The usage pattern is
|
---|
60 | * exactly the same as above except that there is no need to specify the
|
---|
61 | * template argument because it is already done by the shortcut class.
|
---|
62 | *
|
---|
63 | * @param taDepType Dependency type to manage.
|
---|
64 | */
|
---|
65 | template <Machine::StateDependency taDepType = Machine::AnyStateDep>
|
---|
66 | class AutoStateDependency
|
---|
67 | {
|
---|
68 | public:
|
---|
69 |
|
---|
70 | AutoStateDependency(Machine *aThat)
|
---|
71 | : mThat(aThat), mRC(S_OK),
|
---|
72 | mMachineState(MachineState_Null),
|
---|
73 | mRegistered(FALSE)
|
---|
74 | {
|
---|
75 | if (RT_VALID_PTR(aThat))
|
---|
76 | mRC = aThat->i_addStateDependency(taDepType, &mMachineState,
|
---|
77 | &mRegistered);
|
---|
78 | }
|
---|
79 | ~AutoStateDependency()
|
---|
80 | {
|
---|
81 | if (RT_VALID_PTR(mThat) && SUCCEEDED(mRC))
|
---|
82 | mThat->i_releaseStateDependency();
|
---|
83 | }
|
---|
84 |
|
---|
85 | /** Decreases the number of dependencies before the instance is
|
---|
86 | * destroyed. Note that will reset #hrc() to E_FAIL. */
|
---|
87 | void release()
|
---|
88 | {
|
---|
89 | AssertReturnVoid(SUCCEEDED(mRC));
|
---|
90 | if (RT_VALID_PTR(mThat))
|
---|
91 | mThat->i_releaseStateDependency();
|
---|
92 | mRC = E_FAIL;
|
---|
93 | }
|
---|
94 |
|
---|
95 | /** Restores the number of callers after by #release(). #hrc() will be
|
---|
96 | * reset to the result of calling addStateDependency() and must be
|
---|
97 | * rechecked to ensure the operation succeeded. */
|
---|
98 | void add()
|
---|
99 | {
|
---|
100 | AssertReturnVoid(!SUCCEEDED(mRC));
|
---|
101 | if (RT_VALID_PTR(mThat))
|
---|
102 | mRC = mThat->i_addStateDependency(taDepType, &mMachineState,
|
---|
103 | &mRegistered);
|
---|
104 | else
|
---|
105 | mRC = S_OK;
|
---|
106 | }
|
---|
107 |
|
---|
108 | /** Returns the result of Machine::addStateDependency(). */
|
---|
109 | HRESULT hrc() const { return mRC; }
|
---|
110 |
|
---|
111 | /** Shortcut to SUCCEEDED(hrc()). */
|
---|
112 | bool isOk() const { return SUCCEEDED(mRC); }
|
---|
113 |
|
---|
114 | /** Returns the machine state value as returned by
|
---|
115 | * Machine::addStateDependency(). */
|
---|
116 | MachineState_T machineState() const { return mMachineState; }
|
---|
117 |
|
---|
118 | /** Returns the machine state value as returned by
|
---|
119 | * Machine::addStateDependency(). */
|
---|
120 | BOOL machineRegistered() const { return mRegistered; }
|
---|
121 |
|
---|
122 | protected:
|
---|
123 |
|
---|
124 | Machine *mThat;
|
---|
125 | HRESULT mRC;
|
---|
126 | MachineState_T mMachineState;
|
---|
127 | BOOL mRegistered;
|
---|
128 |
|
---|
129 | private:
|
---|
130 |
|
---|
131 | DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoStateDependency);
|
---|
132 | DECLARE_CLS_NEW_DELETE_NOOP(AutoStateDependency);
|
---|
133 | };
|
---|
134 |
|
---|
135 | /**
|
---|
136 | * Shortcut to AutoStateDependency<AnyStateDep>.
|
---|
137 | * See AutoStateDependency to get the usage pattern.
|
---|
138 | *
|
---|
139 | * Accepts any machine state and guarantees the state won't change before
|
---|
140 | * this object is destroyed. If the machine state cannot be protected (as
|
---|
141 | * a result of the state change currently in progress), this instance's
|
---|
142 | * #hrc() method will indicate a failure, and the caller is not allowed to
|
---|
143 | * rely on any particular machine state and should return the failed
|
---|
144 | * result code to the upper level.
|
---|
145 | */
|
---|
146 | typedef AutoStateDependency<Machine::AnyStateDep> AutoAnyStateDependency;
|
---|
147 |
|
---|
148 | /**
|
---|
149 | * Shortcut to AutoStateDependency<MutableStateDep>.
|
---|
150 | * See AutoStateDependency to get the usage pattern.
|
---|
151 | *
|
---|
152 | * Succeeds only if the machine state is in one of the mutable states, and
|
---|
153 | * guarantees the given mutable state won't change before this object is
|
---|
154 | * destroyed. If the machine is not mutable, this instance's #hrc() method
|
---|
155 | * will indicate a failure, and the caller is not allowed to rely on any
|
---|
156 | * particular machine state and should return the failed result code to
|
---|
157 | * the upper level.
|
---|
158 | *
|
---|
159 | * Intended to be used within all setter methods of IMachine
|
---|
160 | * children objects (DVDDrive, NetworkAdapter, AudioAdapter, etc.) to
|
---|
161 | * provide data protection and consistency. There must be no VM process,
|
---|
162 | * i.e. use for settings changes which are valid when the VM is shut down.
|
---|
163 | */
|
---|
164 | typedef AutoStateDependency<Machine::MutableStateDep> AutoMutableStateDependency;
|
---|
165 |
|
---|
166 | /**
|
---|
167 | * Shortcut to AutoStateDependency<MutableOrSavedStateDep>.
|
---|
168 | * See AutoStateDependency to get the usage pattern.
|
---|
169 | *
|
---|
170 | * Succeeds only if the machine state is in one of the mutable states, or
|
---|
171 | * if the machine is in the Saved state, and guarantees the given mutable
|
---|
172 | * state won't change before this object is destroyed. If the machine is
|
---|
173 | * not mutable, this instance's #hrc() method will indicate a failure, and
|
---|
174 | * the caller is not allowed to rely on any particular machine state and
|
---|
175 | * should return the failed result code to the upper level.
|
---|
176 | *
|
---|
177 | * Intended to be used within setter methods of IMachine
|
---|
178 | * children objects that may operate on shut down or Saved machines.
|
---|
179 | */
|
---|
180 | typedef AutoStateDependency<Machine::MutableOrSavedStateDep> AutoMutableOrSavedStateDependency;
|
---|
181 |
|
---|
182 | /**
|
---|
183 | * Shortcut to AutoStateDependency<MutableOrRunningStateDep>.
|
---|
184 | * See AutoStateDependency to get the usage pattern.
|
---|
185 | *
|
---|
186 | * Succeeds only if the machine state is in one of the mutable states, or
|
---|
187 | * if the machine is in the Running or Paused state, and guarantees the
|
---|
188 | * given mutable state won't change before this object is destroyed. If
|
---|
189 | * the machine is not mutable, this instance's #hrc() method will indicate
|
---|
190 | * a failure, and the caller is not allowed to rely on any particular
|
---|
191 | * machine state and should return the failed result code to the upper
|
---|
192 | * level.
|
---|
193 | *
|
---|
194 | * Intended to be used within setter methods of IMachine
|
---|
195 | * children objects that may operate on shut down or running machines.
|
---|
196 | */
|
---|
197 | typedef AutoStateDependency<Machine::MutableOrRunningStateDep> AutoMutableOrRunningStateDependency;
|
---|
198 |
|
---|
199 | /**
|
---|
200 | * Shortcut to AutoStateDependency<MutableOrSavedOrRunningStateDep>.
|
---|
201 | * See AutoStateDependency to get the usage pattern.
|
---|
202 | *
|
---|
203 | * Succeeds only if the machine state is in one of the mutable states, or
|
---|
204 | * if the machine is in the Running, Paused or Saved state, and guarantees
|
---|
205 | * the given mutable state won't change before this object is destroyed.
|
---|
206 | * If the machine is not mutable, this instance's #hrc() method will
|
---|
207 | * indicate a failure, and the caller is not allowed to rely on any
|
---|
208 | * particular machine state and should return the failed result code to
|
---|
209 | * the upper level.
|
---|
210 | *
|
---|
211 | * Intended to be used within setter methods of IMachine
|
---|
212 | * children objects that may operate on shut down, running or saved
|
---|
213 | * machines.
|
---|
214 | */
|
---|
215 | typedef AutoStateDependency<Machine::MutableOrSavedOrRunningStateDep> AutoMutableOrSavedOrRunningStateDependency;
|
---|
216 |
|
---|
217 | #endif /* !MAIN_INCLUDED_AutoStateDep_h */
|
---|
218 |
|
---|