VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/BandwidthGroupImpl.cpp@ 53517

Last change on this file since 53517 was 51498, checked in by vboxsync, 11 years ago

6813 - MachineImpl use of server side wrappers + misc mods on other classes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "BandwidthGroupImpl.h"
19#include "MachineImpl.h"
20#include "Global.h"
21
22#include "AutoCaller.h"
23#include "Logging.h"
24
25#include <iprt/cpp/utils.h>
26
27// constructor / destructor
28/////////////////////////////////////////////////////////////////////////////
29//
30DEFINE_EMPTY_CTOR_DTOR(BandwidthGroup)
31
32HRESULT BandwidthGroup::FinalConstruct()
33{
34 return BaseFinalConstruct();
35}
36
37void BandwidthGroup::FinalRelease()
38{
39 uninit();
40 BaseFinalRelease();
41}
42
43// public initializer/uninitializer for internal purposes only
44/////////////////////////////////////////////////////////////////////////////
45
46/**
47 * Initializes the bandwidth group object.
48 *
49 * @returns COM result indicator.
50 * @param aParent Pointer to our parent object.
51 * @param aName Name of the bandwidth group.
52 * @param aType Type of the bandwidth group (net, disk).
53 * @param aMaxBytesPerSec Maximum bandwidth for the bandwidth group.
54 */
55HRESULT BandwidthGroup::init(BandwidthControl *aParent,
56 const Utf8Str &aName,
57 BandwidthGroupType_T aType,
58 LONG64 aMaxBytesPerSec)
59{
60 LogFlowThisFunc(("aParent=%p aName=\"%s\"\n",
61 aParent, aName.c_str()));
62
63 ComAssertRet(aParent && !aName.isEmpty(), E_INVALIDARG);
64 if ( (aType <= BandwidthGroupType_Null)
65 || (aType > BandwidthGroupType_Network))
66 return setError(E_INVALIDARG,
67 tr("Invalid bandwidth group type type"));
68
69 /* Enclose the state transition NotReady->InInit->Ready */
70 AutoInitSpan autoInitSpan(this);
71 AssertReturn(autoInitSpan.isOk(), E_FAIL);
72
73 m = new Data(aParent);
74
75 /* m->pPeer is left null */
76
77 m->bd.allocate();
78
79 m->bd->strName = aName;
80 m->bd->enmType = aType;
81 m->bd->cReferences = 0;
82 m->bd->aMaxBytesPerSec = aMaxBytesPerSec;
83
84 /* Confirm a successful initialization */
85 autoInitSpan.setSucceeded();
86
87 return S_OK;
88}
89
90/**
91 * Initializes the object given another object
92 * (a kind of copy constructor). This object shares data with
93 * the object passed as an argument.
94 *
95 * @param aReshare
96 * When false, the original object will remain a data owner.
97 * Otherwise, data ownership will be transferred from the original
98 * object to this one.
99 *
100 * @note This object must be destroyed before the original object
101 * it shares data with is destroyed.
102 *
103 * @note Locks @a aThat object for writing if @a aReshare is @c true, or for
104 * reading if @a aReshare is false.
105 */
106HRESULT BandwidthGroup::init(BandwidthControl *aParent,
107 BandwidthGroup *aThat,
108 bool aReshare /* = false */)
109{
110 LogFlowThisFunc(("aParent=%p, aThat=%p, aReshare=%RTbool\n",
111 aParent, aThat, aReshare));
112
113 ComAssertRet(aParent && aThat, E_INVALIDARG);
114
115 /* Enclose the state transition NotReady->InInit->Ready */
116 AutoInitSpan autoInitSpan(this);
117 AssertReturn(autoInitSpan.isOk(), E_FAIL);
118
119 m = new Data(aParent);
120
121 /* sanity */
122 AutoCaller thatCaller(aThat);
123 AssertComRCReturnRC(thatCaller.rc());
124
125 if (aReshare)
126 {
127 AutoWriteLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
128
129 unconst(aThat->m->pPeer) = this;
130 m->bd.attach(aThat->m->bd);
131 }
132 else
133 {
134 unconst(m->pPeer) = aThat;
135
136 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
137 m->bd.share(aThat->m->bd);
138 }
139
140 /* Confirm successful initialization */
141 autoInitSpan.setSucceeded();
142
143 return S_OK;
144}
145
146/**
147 * Initializes the bandwidth group object given another guest object
148 * (a kind of copy constructor). This object makes a private copy of data
149 * of the original object passed as an argument.
150 */
151HRESULT BandwidthGroup::initCopy(BandwidthControl *aParent, BandwidthGroup *aThat)
152{
153 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
154
155 ComAssertRet(aParent && aThat, E_INVALIDARG);
156
157 /* Enclose the state transition NotReady->InInit->Ready */
158 AutoInitSpan autoInitSpan(this);
159 AssertReturn(autoInitSpan.isOk(), E_FAIL);
160
161 m = new Data(aParent);
162 /* m->pPeer is left null */
163
164 AutoCaller thatCaller(aThat);
165 AssertComRCReturnRC(thatCaller.rc());
166
167 AutoReadLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
168 m->bd.attachCopy(aThat->m->bd);
169
170 /* Confirm a successful initialization */
171 autoInitSpan.setSucceeded();
172
173 return S_OK;
174}
175
176
177/**
178 * Uninitializes the instance and sets the ready flag to FALSE.
179 * Called either from FinalRelease() or by the parent when it gets destroyed.
180 */
181void BandwidthGroup::uninit()
182{
183 LogFlowThisFunc(("\n"));
184
185 /* Enclose the state transition Ready->InUninit->NotReady */
186 AutoUninitSpan autoUninitSpan(this);
187 if (autoUninitSpan.uninitDone())
188 return;
189
190 m->bd.free();
191
192 unconst(m->pPeer) = NULL;
193 unconst(m->pParent) = NULL;
194
195 delete m;
196 m = NULL;
197}
198
199HRESULT BandwidthGroup::getName(com::Utf8Str &aName)
200{
201 /* mName is constant during life time, no need to lock */
202 aName = m->bd.data()->strName;
203
204 return S_OK;
205}
206
207HRESULT BandwidthGroup::getType(BandwidthGroupType_T *aType)
208{
209 /* type is constant during life time, no need to lock */
210 *aType = m->bd->enmType;
211
212 return S_OK;
213}
214
215HRESULT BandwidthGroup::getReference(ULONG *aReferences)
216{
217 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
218
219 *aReferences = m->bd->cReferences;
220
221 return S_OK;
222}
223
224HRESULT BandwidthGroup::getMaxBytesPerSec(LONG64 *aMaxBytesPerSec)
225{
226 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
227
228 *aMaxBytesPerSec = m->bd->aMaxBytesPerSec;
229
230 return S_OK;
231}
232
233HRESULT BandwidthGroup::setMaxBytesPerSec(LONG64 aMaxBytesPerSec)
234{
235 if (aMaxBytesPerSec < 0)
236 return setError(E_INVALIDARG,
237 tr("Bandwidth group limit cannot be negative"));
238
239 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
240
241 m->bd.backup();
242 m->bd->aMaxBytesPerSec = aMaxBytesPerSec;
243
244 /* inform direct session if any. */
245 ComObjPtr<Machine> pMachine = m->pParent->i_getMachine();
246 alock.release();
247 pMachine->i_onBandwidthGroupChange(this);
248
249 return S_OK;
250}
251
252// public methods only for internal purposes
253/////////////////////////////////////////////////////////////////////////////
254
255/** @note Locks objects for writing! */
256void BandwidthGroup::i_rollback()
257{
258 AutoCaller autoCaller(this);
259 AssertComRCReturnVoid(autoCaller.rc());
260
261 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
262
263 m->bd.rollback();
264}
265
266/**
267 * @note Locks this object for writing, together with the peer object (also
268 * for writing) if there is one.
269 */
270void BandwidthGroup::i_commit()
271{
272 /* sanity */
273 AutoCaller autoCaller(this);
274 AssertComRCReturnVoid(autoCaller.rc());
275
276 /* sanity too */
277 AutoCaller peerCaller(m->pPeer);
278 AssertComRCReturnVoid(peerCaller.rc());
279
280 /* lock both for writing since we modify both (m->pPeer is "master" so locked
281 * first) */
282 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
283
284 if (m->bd.isBackedUp())
285 {
286 m->bd.commit();
287 if (m->pPeer)
288 {
289 // attach new data to the peer and reshare it
290 m->pPeer->m->bd.attach(m->bd);
291 }
292 }
293}
294
295
296/**
297 * Cancels sharing (if any) by making an independent copy of data.
298 * This operation also resets this object's peer to NULL.
299 *
300 * @note Locks this object for writing, together with the peer object
301 * represented by @a aThat (locked for reading).
302 */
303void BandwidthGroup::i_unshare()
304{
305 /* sanity */
306 AutoCaller autoCaller(this);
307 AssertComRCReturnVoid(autoCaller.rc());
308
309 /* sanity too */
310 AutoCaller peerCaller(m->pPeer);
311 AssertComRCReturnVoid(peerCaller.rc());
312
313 /* peer is not modified, lock it for reading (m->pPeer is "master" so locked
314 * first) */
315 AutoReadLock rl(m->pPeer COMMA_LOCKVAL_SRC_POS);
316 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
317
318 if (m->bd.isShared())
319 {
320 if (!m->bd.isBackedUp())
321 m->bd.backup();
322
323 m->bd.commit();
324 }
325
326 unconst(m->pPeer) = NULL;
327}
328
329void BandwidthGroup::i_reference()
330{
331 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
332 m->bd.backup();
333 m->bd->cReferences++;
334}
335
336void BandwidthGroup::i_release()
337{
338 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
339 m->bd.backup();
340 m->bd->cReferences--;
341}
342
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