VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/TokenImpl.cpp@ 48297

Last change on this file since 48297 was 48297, checked in by vboxsync, 12 years ago

Main/Medium: redesign API level medium locking, needed conversions from MediaList to MediumLockLists in several places, forced cleanups elsewhere, too
Main/Token: introduced token objects for controlling the unlocking, will be used as a general concept in the future
Main/Snapshot: snapshot deletion needed significant cleanups as it was still using many shortcuts, directly calling the API to lock media instead of using lock lists. Now much better, and the online snapshot deletion is also a lot cleaner as it no longer passes unnecessary parameters around which are already known in the machine/snapshot code
Main/MediumLock: small improvements, now has a mode which skips locking already locked media, needed by the Snapshot code where we have overlapping lock lists and have to update the original one instead
Main/Console+Session+Machine: follow-up changes for the online snapshot merging parameter passing simplification, plus an unrelated lock order violation fix in Machine which happens only for inaccessible machines
Main/testcase: update correspondingly
doc: update SDK reference

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.5 KB
Line 
1/* $Id: TokenImpl.cpp 48297 2013-09-05 09:57:44Z vboxsync $ */
2/** @file
3 *
4 * Token COM class implementation: MachineToken and MediumLockToken
5 */
6
7/*
8 * Copyright (C) 2013 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.215389.xyz. 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#include "TokenImpl.h"
20#include "MachineImpl.h"
21#include "MediumImpl.h"
22#include "AutoCaller.h"
23#include "Logging.h"
24
25// constructor / destructor
26/////////////////////////////////////////////////////////////////////////////
27
28DEFINE_EMPTY_CTOR_DTOR(MachineToken)
29
30HRESULT MachineToken::FinalConstruct()
31{
32 return BaseFinalConstruct();
33}
34
35void MachineToken::FinalRelease()
36{
37 uninit();
38
39 BaseFinalRelease();
40}
41
42// public initializer/uninitializer for internal purposes only
43/////////////////////////////////////////////////////////////////////////////
44
45/**
46 * Initializes the token object.
47 *
48 * @param pSessionMachine Pointer to a SessionMachine object.
49 */
50HRESULT MachineToken::init(const ComObjPtr<SessionMachine> &pSessionMachine)
51{
52 LogFlowThisFunc(("pSessionMachine=%p\n", *pSessionMachine));
53
54 ComAssertRet(!pSessionMachine.isNull(), E_INVALIDARG);
55
56 /* Enclose the state transition NotReady->InInit->Ready */
57 AutoInitSpan autoInitSpan(this);
58 AssertReturn(autoInitSpan.isOk(), E_FAIL);
59
60 m.pSessionMachine = pSessionMachine;
61
62 /* Confirm a successful initialization */
63 autoInitSpan.setSucceeded();
64
65 return S_OK;
66}
67
68/**
69 * Uninitializes the instance and sets the ready flag to FALSE.
70 * Called either from FinalRelease() or by the parent when it gets destroyed.
71 */
72void MachineToken::uninit()
73{
74 LogFlowThisFunc(("\n"));
75
76 /* Enclose the state transition Ready->InUninit->NotReady */
77 AutoUninitSpan autoUninitSpan(this);
78 if (autoUninitSpan.uninitDone())
79 return;
80
81 /* Destroy the SessionMachine object, check is paranoia */
82 if (!m.pSessionMachine.isNull())
83 {
84 m.pSessionMachine->uninit();
85 m.pSessionMachine.setNull();
86 }
87}
88
89// IToken methods
90/////////////////////////////////////////////////////////////////////////////
91
92HRESULT MachineToken::abandon(AutoCaller &aAutoCaller)
93{
94 /* have to release the AutoCaller before calling uninit(), self-deadlock */
95 aAutoCaller.release();
96
97 /* uninit does everything we need */
98 uninit();
99 return S_OK;
100}
101
102HRESULT MachineToken::dummy()
103{
104 /* Remember, the wrapper contains the AutoCaller, which means that after
105 * uninit() this code won't be reached any more. */
106
107 /* this is a NOOP, no need to lock */
108
109 return S_OK;
110}
111
112// public methods only for internal purposes
113/////////////////////////////////////////////////////////////////////////////
114
115
116// constructor / destructor
117/////////////////////////////////////////////////////////////////////////////
118
119DEFINE_EMPTY_CTOR_DTOR(MediumLockToken)
120
121HRESULT MediumLockToken::FinalConstruct()
122{
123 return BaseFinalConstruct();
124}
125
126void MediumLockToken::FinalRelease()
127{
128 uninit();
129
130 BaseFinalRelease();
131}
132
133// public initializer/uninitializer for internal purposes only
134/////////////////////////////////////////////////////////////////////////////
135
136/**
137 * Initializes the token object.
138 *
139 * @param pMedium Pointer to a Medium object.
140 * @param fWrite True if this is a write lock, false otherwise.
141 */
142HRESULT MediumLockToken::init(const ComObjPtr<Medium> &pMedium, bool fWrite)
143{
144 LogFlowThisFunc(("pMedium=%p\n", *pMedium));
145
146 ComAssertRet(!pMedium.isNull(), E_INVALIDARG);
147
148 /* Enclose the state transition NotReady->InInit->Ready */
149 AutoInitSpan autoInitSpan(this);
150 AssertReturn(autoInitSpan.isOk(), E_FAIL);
151
152 m.pMedium = pMedium;
153 m.fWrite = fWrite;
154
155 /* Confirm a successful initialization */
156 autoInitSpan.setSucceeded();
157
158 return S_OK;
159}
160
161/**
162 * Uninitializes the instance and sets the ready flag to FALSE.
163 * Called either from FinalRelease() or by the parent when it gets destroyed.
164 */
165void MediumLockToken::uninit()
166{
167 LogFlowThisFunc(("\n"));
168
169 /* Enclose the state transition Ready->InUninit->NotReady */
170 AutoUninitSpan autoUninitSpan(this);
171 if (autoUninitSpan.uninitDone())
172 return;
173
174 /* Release the appropriate lock, check is paranoia */
175 if (!m.pMedium.isNull())
176 {
177 if (m.fWrite)
178 {
179 HRESULT rc = m.pMedium->unlockWrite(NULL);
180 AssertComRC(rc);
181 }
182 else
183 {
184 HRESULT rc = m.pMedium->unlockRead(NULL);
185 AssertComRC(rc);
186 }
187 m.pMedium.setNull();
188 }
189}
190
191// IToken methods
192/////////////////////////////////////////////////////////////////////////////
193
194HRESULT MediumLockToken::abandon(AutoCaller &aAutoCaller)
195{
196 /* have to release the AutoCaller before calling uninit(), self-deadlock */
197 aAutoCaller.release();
198
199 /* uninit does everything we need */
200 uninit();
201 return S_OK;
202}
203
204HRESULT MediumLockToken::dummy()
205{
206 /* Remember, the wrapper contains the AutoCaller, which means that after
207 * uninit() this code won't be reached any more. */
208
209 /* this is a NOOP, no need to lock */
210
211 return S_OK;
212}
213
214// public methods only for internal purposes
215/////////////////////////////////////////////////////////////////////////////
216
217/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette