VirtualBox

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

Last change on this file since 61423 was 61169, checked in by vboxsync, 9 years ago

8238 VBoxSVC settings - BandwidthGroupImpl

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