VirtualBox

source: vbox/trunk/src/VBox/Main/AudioAdapterImpl.cpp@ 3516

Last change on this file since 3516 was 3348, checked in by vboxsync, 18 years ago

Main: Converted AudioAdapter and NetworkAdapter to the new locking scheme.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/** @file
2 *
3 * VirtualBox COM class implementation
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22#include "AudioAdapterImpl.h"
23#include "MachineImpl.h"
24#include "Logging.h"
25
26#include <iprt/cpputils.h>
27
28// constructor / destructor
29/////////////////////////////////////////////////////////////////////////////
30
31DEFINE_EMPTY_CTOR_DTOR (AudioAdapter)
32
33HRESULT AudioAdapter::FinalConstruct()
34{
35 return S_OK;
36}
37
38void AudioAdapter::FinalRelease()
39{
40 uninit ();
41}
42
43// public initializer/uninitializer for internal purposes only
44/////////////////////////////////////////////////////////////////////////////
45
46/**
47 * Initializes the audio adapter object.
48 *
49 * @param aParent Handle of the parent object.
50 */
51HRESULT AudioAdapter::init (Machine *aParent)
52{
53 LogFlowThisFunc (("aParent=%p\n", aParent));
54
55 ComAssertRet (aParent, E_INVALIDARG);
56
57 /* Enclose the state transition NotReady->InInit->Ready */
58 AutoInitSpan autoInitSpan (this);
59 AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED);
60
61 unconst (mParent) = aParent;
62 /* mPeer is left null */
63
64 mData.allocate();
65
66 /* Confirm a successful initialization */
67 autoInitSpan.setSucceeded();
68
69 return S_OK;
70}
71
72/**
73 * Initializes the audio adapter object given another audio adapter object
74 * (a kind of copy constructor). This object shares data with
75 * the object passed as an argument.
76 *
77 * @note This object must be destroyed before the original object
78 * it shares data with is destroyed.
79 *
80 * @note Locks @a aThat object for reading.
81 */
82HRESULT AudioAdapter::init (Machine *aParent, AudioAdapter *aThat)
83{
84 LogFlowThisFunc (("aParent=%p, aThat=%p\n", aParent, aThat));
85
86 ComAssertRet (aParent && aThat, E_INVALIDARG);
87
88 /* Enclose the state transition NotReady->InInit->Ready */
89 AutoInitSpan autoInitSpan (this);
90 AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED);
91
92 unconst (mParent) = aParent;
93 unconst (mPeer) = aThat;
94
95 AutoCaller thatCaller (aThat);
96 AssertComRCReturnRC (thatCaller.rc());
97
98 AutoReaderLock thatLock (aThat);
99 mData.share (aThat->mData);
100
101 /* Confirm a successful initialization */
102 autoInitSpan.setSucceeded();
103
104 return S_OK;
105}
106
107/**
108 * Initializes the guest object given another guest object
109 * (a kind of copy constructor). This object makes a private copy of data
110 * of the original object passed as an argument.
111 *
112 * @note Locks @a aThat object for reading.
113 */
114HRESULT AudioAdapter::initCopy (Machine *aParent, AudioAdapter *aThat)
115{
116 LogFlowThisFunc (("aParent=%p, aThat=%p\n", aParent, aThat));
117
118 ComAssertRet (aParent && aThat, E_INVALIDARG);
119
120 /* Enclose the state transition NotReady->InInit->Ready */
121 AutoInitSpan autoInitSpan (this);
122 AssertReturn (autoInitSpan.isOk(), E_UNEXPECTED);
123
124 unconst (mParent) = aParent;
125 /* mPeer is left null */
126
127 AutoCaller thatCaller (aThat);
128 AssertComRCReturnRC (thatCaller.rc());
129
130 AutoReaderLock thatLock (aThat);
131 mData.attachCopy (aThat->mData);
132
133 /* Confirm a successful initialization */
134 autoInitSpan.setSucceeded();
135
136 return S_OK;
137}
138
139/**
140 * Uninitializes the instance and sets the ready flag to FALSE.
141 * Called either from FinalRelease() or by the parent when it gets destroyed.
142 */
143void AudioAdapter::uninit()
144{
145 LogFlowThisFunc (("\n"));
146
147 /* Enclose the state transition Ready->InUninit->NotReady */
148 AutoUninitSpan autoUninitSpan (this);
149 if (autoUninitSpan.uninitDone())
150 return;
151
152 mData.free();
153
154 unconst (mPeer).setNull();
155 unconst (mParent).setNull();
156}
157
158// IAudioAdapter properties
159/////////////////////////////////////////////////////////////////////////////
160
161STDMETHODIMP AudioAdapter::COMGETTER(Enabled)(BOOL *aEnabled)
162{
163 if (!aEnabled)
164 return E_POINTER;
165
166 AutoCaller autoCaller (this);
167 CheckComRCReturnRC (autoCaller.rc());
168
169 AutoReaderLock alock (this);
170
171 *aEnabled = mData->mEnabled;
172
173 return S_OK;
174}
175
176STDMETHODIMP AudioAdapter::COMSETTER(Enabled)(BOOL aEnabled)
177{
178 AutoCaller autoCaller (this);
179 CheckComRCReturnRC (autoCaller.rc());
180
181 /* the machine needs to be mutable */
182 Machine::AutoMutableStateDependency adep (mParent);
183 CheckComRCReturnRC (adep.rc());
184
185 AutoLock alock (this);
186
187 if (mData->mEnabled != aEnabled)
188 {
189 mData.backup();
190 mData->mEnabled = aEnabled;
191 }
192
193 return S_OK;
194}
195
196STDMETHODIMP AudioAdapter::COMGETTER(AudioDriver)(AudioDriverType_T *aAudioDriver)
197{
198 if (!aAudioDriver)
199 return E_POINTER;
200
201 AutoCaller autoCaller (this);
202 CheckComRCReturnRC (autoCaller.rc());
203
204 AutoReaderLock alock (this);
205
206 *aAudioDriver = mData->mAudioDriver;
207
208 return S_OK;
209}
210
211STDMETHODIMP AudioAdapter::COMSETTER(AudioDriver)(AudioDriverType_T aAudioDriver)
212{
213 AutoCaller autoCaller (this);
214 CheckComRCReturnRC (autoCaller.rc());
215
216 /* the machine needs to be mutable */
217 Machine::AutoMutableStateDependency adep (mParent);
218 CheckComRCReturnRC (adep.rc());
219
220 AutoLock alock (this);
221
222 HRESULT rc = S_OK;
223
224 if (mData->mAudioDriver != aAudioDriver)
225 {
226 /*
227 * which audio driver type are we supposed to use?
228 */
229 switch (aAudioDriver)
230 {
231 case AudioDriverType_NullAudioDriver:
232#ifdef __WIN__
233#ifdef VBOX_WITH_WINMM
234 case AudioDriverType_WINMMAudioDriver:
235#endif
236 case AudioDriverType_DSOUNDAudioDriver:
237#endif /* __WIN__ */
238#ifdef __LINUX__
239 case AudioDriverType_OSSAudioDriver:
240#ifdef VBOX_WITH_ALSA
241 case AudioDriverType_ALSAAudioDriver:
242#endif
243#endif /* __LINUX__ */
244#ifdef __DARWIN__
245 case AudioDriverType_CoreAudioDriver:
246#endif
247#ifdef __OS2__
248 case AudioDriverType_MMPMAudioDriver:
249#endif
250 {
251 mData.backup();
252 mData->mAudioDriver = aAudioDriver;
253 break;
254 }
255
256 default:
257 {
258 AssertMsgFailed (("Wrong audio driver type %d\n",
259 aAudioDriver));
260 rc = E_FAIL;
261 }
262 }
263 }
264
265 return rc;
266}
267
268// IAudioAdapter methods
269/////////////////////////////////////////////////////////////////////////////
270
271// public methods only for internal purposes
272/////////////////////////////////////////////////////////////////////////////
273
274/**
275 * @note Locks this object for writing.
276 */
277bool AudioAdapter::rollback()
278{
279 /* sanity */
280 AutoCaller autoCaller (this);
281 AssertComRCReturn (autoCaller.rc(), false);
282
283 AutoLock alock (this);
284
285 bool changed = false;
286
287 if (mData.isBackedUp())
288 {
289 /* we need to check all data to see whether anything will be changed
290 * after rollback */
291 changed = mData.hasActualChanges();
292 mData.rollback();
293 }
294
295 return changed;
296}
297
298/**
299 * @note Locks this object for writing, together with the peer object (also
300 * for writing) if there is one.
301 */
302void AudioAdapter::commit()
303{
304 /* sanity */
305 AutoCaller autoCaller (this);
306 AssertComRCReturnVoid (autoCaller.rc());
307
308 /* sanity too */
309 AutoCaller thatCaller (mPeer);
310 AssertComRCReturnVoid (thatCaller.rc());
311
312 /* lock both for writing since we modify both */
313 AutoMultiLock <2> alock (this->wlock(), AutoLock::maybeWlock (mPeer));
314
315 if (mData.isBackedUp())
316 {
317 mData.commit();
318 if (mPeer)
319 {
320 /* attach new data to the peer and reshare it */
321 mPeer->mData.attach (mData);
322 }
323 }
324}
325
326/**
327 * @note Locks this object for writing, together with the peer object
328 * represented by @a aThat (locked for reading).
329 */
330void AudioAdapter::copyFrom (AudioAdapter *aThat)
331{
332 AssertReturnVoid (aThat != NULL);
333
334 /* sanity */
335 AutoCaller autoCaller (this);
336 AssertComRCReturnVoid (autoCaller.rc());
337
338 /* sanity too */
339 AutoCaller thatCaller (mPeer);
340 AssertComRCReturnVoid (thatCaller.rc());
341
342 /* peer is not modified, lock it for reading */
343 AutoMultiLock <2> alock (this->wlock(), aThat->rlock());
344
345 /* this will back up current data */
346 mData.assignCopy (aThat->mData);
347}
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