VirtualBox

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

Last change on this file since 94722 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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