/** * Initializes the Serial Port object given another serial port object * (a kind of copy constructor). This object shares data with * the object passed as an argument. * * @note This object must be destroyed before the original object * it shares data with is destroyed. * * @note Locks @a aThat object for reading. */ HRESULT SerialPort::init(Machine *aParent, SerialPort *aThat) { LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat)); ComAssertRet(aParent && aThat, E_INVALIDARG); /* Enclose the state transition NotReady->InInit->Ready */ AutoInitSpan autoInitSpan(this); AssertReturn(autoInitSpan.isOk(), E_FAIL); m = new Data(); unconst(m->pMachine) = aParent; unconst(m->pPeer) = aThat; AutoCaller thatCaller (aThat); AssertComRCReturnRC(thatCaller.rc()); AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS); m->bd.share (aThat->m->bd); /* Confirm a successful initialization */ autoInitSpan.setSucceeded(); return S_OK; }
/** * Initializes the guest object given another guest object * (a kind of copy constructor). This object makes a private copy of data * of the original object passed as an argument. * * @note Locks @a aThat object for reading. */ HRESULT AudioAdapter::initCopy (Machine *aParent, AudioAdapter *aThat) { LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat)); ComAssertRet(aParent && aThat, E_INVALIDARG); /* Enclose the state transition NotReady->InInit->Ready */ AutoInitSpan autoInitSpan(this); AssertReturn(autoInitSpan.isOk(), E_FAIL); unconst(mParent) = aParent; /* mPeer is left null */ AutoCaller thatCaller (aThat); AssertComRCReturnRC(thatCaller.rc()); AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS); mData = new Data(); mData->m.attachCopy (aThat->mData->m); /* Confirm a successful initialization */ autoInitSpan.setSucceeded(); return S_OK; }
/** * Cancels sharing (if any) by making an independent copy of data. * This operation also resets this object's peer to NULL. * * @note Locks this object for writing, together with the peer object * represented by @a aThat (locked for reading). */ void USBDeviceFilter::unshare() { /* sanity */ AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); /* sanity too */ AutoCaller peerCaller (mPeer); AssertComRCReturnVoid (peerCaller.rc()); /* peer is not modified, lock it for reading (mPeer is "master" so locked * first) */ AutoReadLock rl(mPeer COMMA_LOCKVAL_SRC_POS); AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS); if (mData.isShared()) { if (!mData.isBackedUp()) mData.backup(); mData.commit(); } unconst(mPeer) = NULL; }
/** * Initializes the guest object given another guest object * (a kind of copy constructor). This object makes a private copy of data * of the original object passed as an argument. * * @note Locks @a aThat object for reading. */ HRESULT USBDeviceFilter::initCopy (USBDeviceFilters *aParent, USBDeviceFilter *aThat) { LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat)); ComAssertRet(aParent && aThat, E_INVALIDARG); /* Enclose the state transition NotReady->InInit->Ready */ AutoInitSpan autoInitSpan(this); AssertReturn(autoInitSpan.isOk(), E_FAIL); unconst(mParent) = aParent; /* mPeer is left null */ m_fModified = false; /* sanity */ AutoCaller thatCaller (aThat); AssertComRCReturnRC(thatCaller.rc()); AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS); mData.attachCopy (aThat->mData); /* reset the arbitrary ID field * (this field is something unique that two distinct objects, even if they * are deep copies of each other, should not share) */ mData->mId = NULL; mInList = aThat->mInList; /* Confirm successful initialization */ autoInitSpan.setSucceeded(); return S_OK; }
/** * @note Locks this object for writing, together with the peer object * represented by @a aThat (locked for reading). */ void USBController::copyFrom (USBController *aThat) { AssertReturnVoid (aThat != NULL); /* sanity */ AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); /* sanity too */ AutoCaller thatCaller (aThat); AssertComRCReturnVoid (thatCaller.rc()); /* even more sanity */ AutoAnyStateDependency adep(m->pParent); AssertComRCReturnVoid (adep.rc()); /* Machine::copyFrom() may not be called when the VM is running */ AssertReturnVoid (!Global::IsOnline (adep.machineState())); /* peer is not modified, lock it for reading (aThat is "master" so locked * first) */ AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS); AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS); /* this will back up current data */ m->bd.assignCopy(aThat->m->bd); #ifdef VBOX_WITH_USB /* Note that we won't inform the USB proxy about new filters since the VM is * not running when we are here and therefore no need to do so */ /* create private copies of all filters */ m->llDeviceFilters.backup(); m->llDeviceFilters->clear(); for (DeviceFilterList::const_iterator it = aThat->m->llDeviceFilters->begin(); it != aThat->m->llDeviceFilters->end(); ++ it) { ComObjPtr<USBDeviceFilter> filter; filter.createObject(); filter->initCopy (this, *it); m->llDeviceFilters->push_back (filter); } #endif /* VBOX_WITH_USB */ }
/** * Initializes the object given another object * (a kind of copy constructor). This object shares data with * the object passed as an argument. * * @param aReshare * When false, the original object will remain a data owner. * Otherwise, data ownership will be transferred from the original * object to this one. * * @note This object must be destroyed before the original object * it shares data with is destroyed. * * @note Locks @a aThat object for writing if @a aReshare is @c true, or for * reading if @a aReshare is false. */ HRESULT USBDeviceFilter::init (USBDeviceFilters *aParent, USBDeviceFilter *aThat, bool aReshare /* = false */) { LogFlowThisFunc(("aParent=%p, aThat=%p, aReshare=%RTbool\n", aParent, aThat, aReshare)); ComAssertRet(aParent && aThat, E_INVALIDARG); /* Enclose the state transition NotReady->InInit->Ready */ AutoInitSpan autoInitSpan(this); AssertReturn(autoInitSpan.isOk(), E_FAIL); unconst(mParent) = aParent; m_fModified = false; /* sanity */ AutoCaller thatCaller (aThat); AssertComRCReturnRC(thatCaller.rc()); if (aReshare) { AutoWriteLock thatLock(aThat COMMA_LOCKVAL_SRC_POS); unconst(aThat->mPeer) = this; mData.attach (aThat->mData); } else { unconst(mPeer) = aThat; AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS); mData.share (aThat->mData); } /* the arbitrary ID field is not reset because * the copy is a shadow of the original */ mInList = aThat->mInList; /* Confirm successful initialization */ autoInitSpan.setSucceeded(); return S_OK; }
HRESULT MachineToken::abandon(AutoCaller &aAutoCaller) { /* have to release the AutoCaller before calling uninit(), self-deadlock */ aAutoCaller.release(); /* uninit does everything we need */ uninit(true); return S_OK; }
/** * @note Locks this object for writing, together with the peer object * represented by @a aThat (locked for reading). */ void AudioAdapter::i_copyFrom(AudioAdapter *aThat) { AssertReturnVoid (aThat != NULL); /* sanity */ AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); /* sanity too */ AutoCaller thatCaller (aThat); AssertComRCReturnVoid (thatCaller.rc()); /* peer is not modified, lock it for reading (aThat is "master" so locked * first) */ AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS); AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS); /* this will back up current data */ mData->m.assignCopy(aThat->mData->m); }
/** * @note Locks this object for writing, together with the peer object (also * for writing) if there is one. */ void AudioAdapter::i_commit() { /* sanity */ AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); /* sanity too */ AutoCaller peerCaller (mPeer); AssertComRCReturnVoid (peerCaller.rc()); /* lock both for writing since we modify both (mPeer is "master" so locked * first) */ AutoMultiWriteLock2 alock(mPeer, this COMMA_LOCKVAL_SRC_POS); if (mData->m.isBackedUp()) { mData->m.commit(); if (mPeer) { /* attach new data to the peer and reshare it */ mPeer->mData->m.attach (mData->m); } } }
/** * @note Locks this object for writing, together with the peer object (also * for writing) if there is one. */ void StorageController::commit() { /* sanity */ AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); /* sanity too */ AutoCaller peerCaller (m->pPeer); AssertComRCReturnVoid (peerCaller.rc()); /* lock both for writing since we modify both (m->pPeer is "master" so locked * first) */ AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS); if (m->bd.isBackedUp()) { m->bd.commit(); if (m->pPeer) { // attach new data to the peer and reshare it m->pPeer->m->bd.attach (m->bd); } } }