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