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-2010 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 and
|
---|
43 | * AutoMutableOrSavedStateDependency. The usage pattern is exactly the
|
---|
44 | * same as above except that there is no need to specify the template
|
---|
45 | * argument because it is already done by the shortcut class.
|
---|
46 | *
|
---|
47 | * @param taDepType Dependecy type to manage.
|
---|
48 | */
|
---|
49 | template <Machine::StateDependency taDepType = Machine::AnyStateDep>
|
---|
50 | class AutoStateDependency
|
---|
51 | {
|
---|
52 | public:
|
---|
53 |
|
---|
54 | AutoStateDependency(Machine *aThat)
|
---|
55 | : mThat(aThat), mRC(S_OK),
|
---|
56 | mMachineState(MachineState_Null),
|
---|
57 | mRegistered(FALSE)
|
---|
58 | {
|
---|
59 | Assert(aThat);
|
---|
60 | mRC = aThat->addStateDependency(taDepType, &mMachineState,
|
---|
61 | &mRegistered);
|
---|
62 | }
|
---|
63 | ~AutoStateDependency()
|
---|
64 | {
|
---|
65 | if (SUCCEEDED(mRC))
|
---|
66 | mThat->releaseStateDependency();
|
---|
67 | }
|
---|
68 |
|
---|
69 | /** Decreases the number of dependencies before the instance is
|
---|
70 | * destroyed. Note that will reset #rc() to E_FAIL. */
|
---|
71 | void release()
|
---|
72 | {
|
---|
73 | AssertReturnVoid(SUCCEEDED(mRC));
|
---|
74 | mThat->releaseStateDependency();
|
---|
75 | mRC = E_FAIL;
|
---|
76 | }
|
---|
77 |
|
---|
78 | /** Restores the number of callers after by #release(). #rc() will be
|
---|
79 | * reset to the result of calling addStateDependency() and must be
|
---|
80 | * rechecked to ensure the operation succeeded. */
|
---|
81 | void add()
|
---|
82 | {
|
---|
83 | AssertReturnVoid(!SUCCEEDED(mRC));
|
---|
84 | mRC = mThat->addStateDependency(taDepType, &mMachineState,
|
---|
85 | &mRegistered);
|
---|
86 | }
|
---|
87 |
|
---|
88 | /** Returns the result of Machine::addStateDependency(). */
|
---|
89 | HRESULT rc() const { return mRC; }
|
---|
90 |
|
---|
91 | /** Shortcut to SUCCEEDED(rc()). */
|
---|
92 | bool isOk() const { return SUCCEEDED(mRC); }
|
---|
93 |
|
---|
94 | /** Returns the machine state value as returned by
|
---|
95 | * Machine::addStateDependency(). */
|
---|
96 | MachineState_T machineState() const { return mMachineState; }
|
---|
97 |
|
---|
98 | /** Returns the machine state value as returned by
|
---|
99 | * Machine::addStateDependency(). */
|
---|
100 | BOOL machineRegistered() const { return mRegistered; }
|
---|
101 |
|
---|
102 | protected:
|
---|
103 |
|
---|
104 | Machine *mThat;
|
---|
105 | HRESULT mRC;
|
---|
106 | MachineState_T mMachineState;
|
---|
107 | BOOL mRegistered;
|
---|
108 |
|
---|
109 | private:
|
---|
110 |
|
---|
111 | DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoStateDependency)
|
---|
112 | DECLARE_CLS_NEW_DELETE_NOOP(AutoStateDependency)
|
---|
113 | };
|
---|
114 |
|
---|
115 | /**
|
---|
116 | * Shortcut to AutoStateDependency<AnyStateDep>.
|
---|
117 | * See AutoStateDependency to get the usage pattern.
|
---|
118 | *
|
---|
119 | * Accepts any machine state and guarantees the state won't change before
|
---|
120 | * this object is destroyed. If the machine state cannot be protected (as
|
---|
121 | * a result of the state change currently in progress), this instance's
|
---|
122 | * #rc() method will indicate a failure, and the caller is not allowed to
|
---|
123 | * rely on any particular machine state and should return the failed
|
---|
124 | * result code to the upper level.
|
---|
125 | */
|
---|
126 | typedef AutoStateDependency<Machine::AnyStateDep> AutoAnyStateDependency;
|
---|
127 |
|
---|
128 | /**
|
---|
129 | * Shortcut to AutoStateDependency<MutableStateDep>.
|
---|
130 | * See AutoStateDependency to get the usage pattern.
|
---|
131 | *
|
---|
132 | * Succeeds only if the machine state is in one of the mutable states, and
|
---|
133 | * guarantees the given mutable state won't change before this object is
|
---|
134 | * destroyed. If the machine is not mutable, this instance's #rc() method
|
---|
135 | * will indicate a failure, and the caller is not allowed to rely on any
|
---|
136 | * particular machine state and should return the failed result code to
|
---|
137 | * the upper level.
|
---|
138 | *
|
---|
139 | * Intended to be used within all setter methods of IMachine
|
---|
140 | * children objects (DVDDrive, NetworkAdapter, AudioAdapter, etc.) to
|
---|
141 | * provide data protection and consistency.
|
---|
142 | */
|
---|
143 | typedef AutoStateDependency<Machine::MutableStateDep> AutoMutableStateDependency;
|
---|
144 |
|
---|
145 | /**
|
---|
146 | * Shortcut to AutoStateDependency<MutableOrSavedStateDep>.
|
---|
147 | * See AutoStateDependency to get the usage pattern.
|
---|
148 | *
|
---|
149 | * Succeeds only if the machine state is in one of the mutable states, or
|
---|
150 | * if the machine is in the Saved state, and guarantees the given mutable
|
---|
151 | * state won't change before this object is destroyed. If the machine is
|
---|
152 | * not mutable, this instance's #rc() method will indicate a failure, and
|
---|
153 | * the caller is not allowed to rely on any particular machine state and
|
---|
154 | * should return the failed result code to the upper level.
|
---|
155 | *
|
---|
156 | * Intended to be used within setter methods of IMachine
|
---|
157 | * children objects that may also operate on Saved machines.
|
---|
158 | */
|
---|
159 | typedef AutoStateDependency<Machine::MutableOrSavedStateDep> AutoMutableOrSavedStateDependency;
|
---|
160 |
|
---|
161 | #endif // ____H_AUTOSTATEDEP
|
---|
162 |
|
---|