VirtualBox

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

Last change on this file since 106297 was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

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