Changeset 40257 in vbox
- Timestamp:
- Feb 27, 2012 9:25:12 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/com/AutoLock.h
r38773 r40257 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 401 401 * which derive from this. 402 402 * 403 * In addition to utility methods for subclasses, this implements the public 404 * leave/enter methods, which are common to all 405 * write locks. 403 * It has some utility methods for subclasses. 406 404 */ 407 405 class AutoWriteLockBase : public AutoLockBase … … 427 425 virtual void callLockImpl(LockHandle &l); 428 426 virtual void callUnlockImpl(LockHandle &l); 429 430 public:431 void leave();432 void enter();433 427 }; 434 428 -
trunk/src/VBox/Main/glue/AutoLock.cpp
r38773 r40257 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 71 71 { LOCKCLASS_MACHINEOBJECT, "5-MACHINEOBJECT" }, 72 72 { LOCKCLASS_SNAPSHOTOBJECT, "6-SNAPSHOTOBJECT" }, 73 { LOCKCLASS_ LISTOFMEDIA, "7-LISTOFMEDIA" },74 { LOCKCLASS_LISTOF OTHEROBJECTS, "8-LISTOFOTHEROBJECTS" },75 { LOCKCLASS_ MEDIUMQUERY, "9-MEDIUMQUERY" },73 { LOCKCLASS_MEDIUMQUERY, "7-MEDIUMQUERY" }, 74 { LOCKCLASS_LISTOFMEDIA, "8-LISTOFMEDIA" }, 75 { LOCKCLASS_LISTOFOTHEROBJECTS, "9-LISTOFOTHEROBJECTS" }, 76 76 { LOCKCLASS_OTHEROBJECT, "10-OTHEROBJECT" }, 77 77 { LOCKCLASS_USBLIST, "11-USBLIST" }, … … 303 303 304 304 typedef std::vector<LockHandle*> HandlesVector; 305 typedef std::vector<uint32_t> CountsVector;306 305 307 306 struct AutoLockBase::Data … … 315 314 ) 316 315 : fIsLocked(false), 317 aHandles(cHandles), // size of array 318 acUnlockedInLeave(cHandles) 316 aHandles(cHandles) // size of array 319 317 #ifdef VBOX_WITH_MAIN_LOCK_VALIDATION 320 318 , pcszFile(pcszFile_), … … 324 322 { 325 323 for (uint32_t i = 0; i < cHandles; ++i) 326 {327 acUnlockedInLeave[i] = 0;328 324 aHandles[i] = NULL; 329 }330 325 } 331 326 … … 335 330 // and AutoReadLock, there will only be one item on the list; with the 336 331 // AutoMulti* derivatives, there will be multiple 337 CountsVector acUnlockedInLeave; // for each lock handle, how many times the handle was unlocked in leave(); otherwise 0338 332 339 333 #ifdef VBOX_WITH_MAIN_LOCK_VALIDATION … … 415 409 * Destructor implementation that can also be called explicitly, if required. 416 410 * Restores the exact state before the AutoLock was created; that is, unlocks 417 * all contained semaphores and might actually lock them again if leave() 418 * was called during the AutoLock's lifetime. 411 * all contained semaphores. 419 412 */ 420 413 void AutoLockBase::cleanup() 421 414 { 422 bool fAnyUnlockedInLeave = false; 423 424 uint32_t i = 0; 425 for (HandlesVector::iterator it = m->aHandles.begin(); 426 it != m->aHandles.end(); 427 ++it) 428 { 429 LockHandle *pHandle = *it; 430 if (pHandle) 431 { 432 if (m->acUnlockedInLeave[i]) 433 { 434 // there was a leave() before the destruction: then restore the 435 // lock level that might have been set by locks other than our own 436 if (m->fIsLocked) 437 { 438 --m->acUnlockedInLeave[i]; 439 fAnyUnlockedInLeave = true; 440 } 441 for (; m->acUnlockedInLeave[i]; --m->acUnlockedInLeave[i]) 442 callLockImpl(*pHandle); 443 } 444 } 445 ++i; 446 } 447 448 if (m->fIsLocked && !fAnyUnlockedInLeave) 415 if (m->fIsLocked) 449 416 callUnlockOnAllHandles(); 450 417 } … … 553 520 { 554 521 l.unlockWrite(); 555 }556 557 /**558 * Causes the current thread to completely release the write lock to make559 * the managed semaphore immediately available for locking by other threads.560 *561 * This implies that all nested write locks on the semaphore will be562 * released, even those that were acquired through the calls to #lock()563 * methods of all other AutoWriteLock/AutoReadLock instances managing the564 * <b>same</b> read/write semaphore.565 *566 * After calling this method, the only method you are allowed to call is567 * #enter(). It will acquire the write lock again and restore the same568 * level of nesting as it had before calling #leave().569 *570 * If this instance is destroyed without calling #enter(), the destructor571 * will try to restore the write lock level that existed when #leave() was572 * called minus the number of nested #lock() calls made on this instance573 * itself. This is done to preserve lock levels of other574 * AutoWriteLock/AutoReadLock instances managing the same semaphore (if575 * any). Tiis also means that the destructor may indefinitely block if a576 * write or a read lock is owned by some other thread by that time.577 */578 void AutoWriteLockBase::leave()579 {580 AssertMsg(m->fIsLocked, ("m->fIsLocked is false, cannot leave()!"));581 582 // unlock in reverse order!583 uint32_t i = m->aHandles.size();584 for (HandlesVector::reverse_iterator it = m->aHandles.rbegin();585 it != m->aHandles.rend();586 ++it)587 {588 --i; // array index is zero based, decrement with every loop since we iterate backwards589 LockHandle *pHandle = *it;590 if (pHandle)591 {592 AssertMsg(m->acUnlockedInLeave[i] == 0, ("m->cUnlockedInLeave[%d] is %d, must be 0! Called leave() twice?", i, m->acUnlockedInLeave[i]));593 m->acUnlockedInLeave[i] = pHandle->writeLockLevel();594 AssertMsg(m->acUnlockedInLeave[i] >= 1, ("m->cUnlockedInLeave[%d] is %d, must be >=1!", i, m->acUnlockedInLeave[i]));595 596 for (uint32_t left = m->acUnlockedInLeave[i];597 left;598 --left)599 callUnlockImpl(*pHandle);600 }601 }602 }603 604 /**605 * Causes the current thread to restore the write lock level after the606 * #leave() call. This call will indefinitely block if another thread has607 * successfully acquired a write or a read lock on the same semaphore in608 * between.609 */610 void AutoWriteLockBase::enter()611 {612 AssertMsg(m->fIsLocked, ("m->fIsLocked is false, cannot enter()!"));613 614 uint32_t i = 0;615 for (HandlesVector::iterator it = m->aHandles.begin();616 it != m->aHandles.end();617 ++it)618 {619 LockHandle *pHandle = *it;620 if (pHandle)621 {622 AssertMsg(m->acUnlockedInLeave[i] != 0, ("m->cUnlockedInLeave[%d] is 0! enter() without leave()?", i));623 624 for (; m->acUnlockedInLeave[i]; --m->acUnlockedInLeave[i])625 callLockImpl(*pHandle);626 }627 ++i;628 }629 522 } 630 523 -
trunk/src/VBox/Main/include/MediumImpl.h
r38499 r40257 269 269 270 270 HRESULT queryInfo(bool fSetImageId, bool fSetParentId); 271 HRESULT lockRead(MediumState_T *aState, bool fWithinQueryInfo); 272 HRESULT lockWrite(MediumState_T *aState, bool fWithinQueryInfo); 271 273 272 274 HRESULT canClose(); -
trunk/src/VBox/Main/include/VirtualBoxImpl.h
r38818 r40257 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 260 260 void copyPathRelativeToConfig(const Utf8Str &strSource, Utf8Str &strTarget); 261 261 262 HRESULT registerHardDisk(Medium *aHardDisk, GuidList *pllRegistriesThatNeedSaving); 263 HRESULT unregisterHardDisk(Medium *aHardDisk, GuidList *pllRegistriesThatNeedSaving); 264 265 HRESULT registerImage(Medium *aImage, DeviceType_T argType, GuidList *pllRegistriesThatNeedSaving); 266 HRESULT unregisterImage(Medium *aImage, DeviceType_T argType, GuidList *pllRegistriesThatNeedSaving); 262 HRESULT registerMedium(Medium *pMedium, ComObjPtr<Medium> *ppMedium, DeviceType_T argType, GuidList *pllRegistriesThatNeedSaving); 263 HRESULT unregisterMedium(Medium *pMedium, GuidList *pllRegistriesThatNeedSaving); 267 264 268 265 void pushMediumToListWithChildren(MediaList &llMedia, Medium *pMedium); … … 301 298 const Utf8Str &aLocation, 302 299 Utf8Str &aConflictType, 303 bool &fIdentical);300 ComObjPtr<Medium> *pDupMedium); 304 301 305 302 HRESULT registerMachine(Machine *aMachine); -
trunk/src/VBox/Main/src-all/ProgressImpl.cpp
r38181 r40257 6 6 7 7 /* 8 * Copyright (C) 2006-201 0Oracle Corporation8 * Copyright (C) 2006-2012 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 820 820 { 821 821 mWaitersCount++; 822 alock. leave();822 alock.release(); 823 823 vrc = RTSemEventMultiWait(mCompletedSem, 824 824 fForever ? RT_INDEFINITE_WAIT : (RTMSINTERVAL)timeLeft); 825 alock. enter();825 alock.acquire(); 826 826 mWaitersCount--; 827 827 … … 884 884 { 885 885 mWaitersCount ++; 886 alock. leave();886 alock.release(); 887 887 vrc = RTSemEventMultiWait(mCompletedSem, 888 888 fForever ? RT_INDEFINITE_WAIT : (unsigned) timeLeft); 889 alock. enter();889 alock.acquire(); 890 890 mWaitersCount--; 891 891 … … 1664 1664 while (!mCompleted && (forever || timeLeft > 0)) 1665 1665 { 1666 alock. leave();1666 alock.release(); 1667 1667 rc = mProgresses.back()->WaitForCompletion(forever ? -1 : (LONG) timeLeft); 1668 alock. enter();1668 alock.acquire(); 1669 1669 1670 1670 if (SUCCEEDED(rc)) … … 1748 1748 (forever || timeLeft > 0)) 1749 1749 { 1750 alock. leave();1750 alock.release(); 1751 1751 /* wait for the appropriate progress operation completion */ 1752 1752 rc = mProgresses[progress]-> WaitForOperationCompletion(operation, 1753 1753 forever ? -1 : (LONG) timeLeft); 1754 alock. enter();1754 alock.acquire(); 1755 1755 1756 1756 if (SUCCEEDED(rc)) -
trunk/src/VBox/Main/src-all/VirtualBoxBase.cpp
r38533 r40257 7 7 8 8 /* 9 * Copyright (C) 2006-201 0Oracle Corporation9 * Copyright (C) 2006-2012 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 209 209 LogFlowThisFunc(("Waiting for AutoInitSpan/AutoReinitSpan to finish...\n")); 210 210 211 stateLock. leave();211 stateLock.release(); 212 212 RTSemEventMultiWait (mInitUninitSem, RT_INDEFINITE_WAIT); 213 stateLock. enter();213 stateLock.acquire(); 214 214 215 215 if (-- mInitUninitWaiters == 0) … … 776 776 { 777 777 mObj->setState(VirtualBoxBase::InitFailed); 778 /* leave the lock to prevent nesting when uninit() is called */779 stateLock. leave();778 /* release the lock to prevent nesting when uninit() is called */ 779 stateLock.acquire(); 780 780 /* call uninit() to let the object uninit itself after failed init() */ 781 781 mObj->uninit(); … … 906 906 mObj)); 907 907 908 stateLock. leave();908 stateLock.release(); 909 909 RTSemEventMultiWait(mObj->mInitUninitSem, RT_INDEFINITE_WAIT); 910 stateLock. enter();910 stateLock.acquire(); 911 911 912 912 if (--mObj->mInitUninitWaiters == 0) … … 935 935 mObj, mObj->mCallers)); 936 936 937 stateLock. leave();937 stateLock.release(); 938 938 RTSemEventWait(mObj->mZeroCallersSem, RT_INDEFINITE_WAIT); 939 939 } -
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r40084 r40257 2077 2077 return ptrVM.rc(); 2078 2078 2079 /* leave the lock before a VMR3* call (EMT will call us back)! */2080 alock. leave();2079 /* release the lock before a VMR3* call (EMT will call us back)! */ 2080 alock.release(); 2081 2081 2082 2082 int vrc = VMR3Reset(ptrVM); … … 2290 2290 this, pVM, aCpu); 2291 2291 2292 /* leave the lock before a VMR3* call (EMT will call us back)! */2292 /* release the lock before a VMR3* call (EMT will call us back)! */ 2293 2293 alock.release(); 2294 2294 … … 2354 2354 LogFlowThisFunc(("Sending PAUSE request...\n")); 2355 2355 2356 /* leave the lock before a VMR3* call (EMT will call us back)! */2357 alock. leave();2356 /* release the lock before a VMR3* call (EMT will call us back)! */ 2357 alock.release(); 2358 2358 2359 2359 int vrc = VMR3Suspend(ptrVM); … … 2389 2389 LogFlowThisFunc(("Sending RESUME request...\n")); 2390 2390 2391 /* leave the lock before a VMR3* call (EMT will call us back)! */2392 alock. leave();2391 /* release the lock before a VMR3* call (EMT will call us back)! */ 2392 alock.release(); 2393 2393 2394 2394 #ifdef VBOX_WITH_EXTPACK … … 2434 2434 if (!ptrVM.isOk()) 2435 2435 return ptrVM.rc(); 2436 /** @todo leave the console lock? */ 2436 2437 /** @todo release the console lock? */ 2437 2438 2438 2439 /* get the acpi device interface and press the button. */ … … 2481 2482 if (!ptrVM.isOk()) 2482 2483 return ptrVM.rc(); 2483 /** @todo leave the console lock? */ 2484 2485 /** @todo release the console lock? */ 2484 2486 2485 2487 /* get the acpi device interface and check if the button press was handled. */ … … 2536 2538 return ptrVM.rc(); 2537 2539 2538 /** @todo leave the console lock? */2540 /** @todo release the console lock? */ 2539 2541 2540 2542 /* get the acpi device interface and query the information. */ … … 2577 2579 return ptrVM.rc(); 2578 2580 2579 /** @todo leave the console lock? */2581 /** @todo release the console lock? */ 2580 2582 2581 2583 /* get the acpi device interface and press the sleep button. */ … … 2679 2681 /* 2680 2682 * If we fail here it means a PowerDown() call happened on another 2681 * thread while we were doing Pause() (which leaves the Console lock).2683 * thread while we were doing Pause() (which releases the Console lock). 2682 2684 * We assign PowerDown() a higher precedence than SaveState(), 2683 2685 * therefore just return the error to the caller. … … 2887 2889 tr("The virtual machine does not have a USB controller")); 2888 2890 2889 /* leave the lock because the USB Proxy service may call us back2891 /* release the lock because the USB Proxy service may call us back 2890 2892 * (via onUSBDeviceAttach()) */ 2891 alock. leave();2893 alock.release(); 2892 2894 2893 2895 /* Request the device capture */ … … 2932 2934 * Inform the USB device and USB proxy about what's cooking. 2933 2935 */ 2934 alock. leave();2936 alock.release(); 2935 2937 HRESULT rc2 = mControl->DetachUSBDevice(aId, false /* aDone */); 2936 2938 if (FAILED(rc2)) 2937 2939 return rc2; 2938 alock. enter();2940 alock.acquire(); 2939 2941 2940 2942 /* Request the PDM to detach the USB device. */ … … 2943 2945 if (SUCCEEDED(rc)) 2944 2946 { 2945 /* leave the lock since we don't need it any more (note though that2947 /* release the lock since we don't need it any more (note though that 2946 2948 * the USB Proxy service must not call us back here) */ 2947 alock. leave();2949 alock.release(); 2948 2950 2949 2951 /* Request the device release. Even if it fails, the device will … … 3269 3271 /* 3270 3272 * If we fail here it means a PowerDown() call happened on another 3271 * thread while we were doing Pause() (which leaves the Console lock).3273 * thread while we were doing Pause() (which releases the Console lock). 3272 3274 * We assign PowerDown() a higher precedence than TakeSnapshot(), 3273 3275 * therefore just return the error to the caller. … … 3595 3597 fForce); 3596 3598 3597 /* leave the lock before waiting for a result (EMT will call us back!) */3598 alock. leave();3599 /* release the lock before waiting for a result (EMT will call us back!) */ 3600 alock.release(); 3599 3601 3600 3602 if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc)) … … 3848 3850 aMediumAttachment); 3849 3851 3850 /* leave the lock before waiting for a result (EMT will call us back!) */3851 alock. leave();3852 /* release the lock before waiting for a result (EMT will call us back!) */ 3853 alock.release(); 3852 3854 3853 3855 if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc)) … … 4089 4091 aMediumAttachment); 4090 4092 4091 /* leave the lock before waiting for a result (EMT will call us back!) */4092 alock. leave();4093 /* release the lock before waiting for a result (EMT will call us back!) */ 4094 alock.release(); 4093 4095 4094 4096 if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc)) … … 4498 4500 this, ptrVM.raw(), pszDevice, uInstance, uLun, aNetworkAdapter); 4499 4501 4500 /* leave the lock before waiting for a result (EMT will call us back!) */4501 alock. leave();4502 /* release the lock before waiting for a result (EMT will call us back!) */ 4503 alock.release(); 4502 4504 4503 4505 if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc)) … … 4833 4835 { 4834 4836 /* VRDP server may call this Console object back from other threads (VRDP INPUT or OUTPUT). */ 4835 alock. leave();4837 alock.release(); 4836 4838 4837 4839 if (vrdpEnabled) … … 4852 4854 } 4853 4855 4854 alock. enter();4856 alock.acquire(); 4855 4857 } 4856 4858 } … … 6688 6690 /* ---------------------------------------------------------------------- 6689 6691 * DONE with necessary state changes, perform the power down actions (it's 6690 * safe to leave the object lock now if needed)6692 * safe to release the object lock now if needed) 6691 6693 * ---------------------------------------------------------------------- */ 6692 6694 … … 6699 6701 /* Leave the lock since EMT will call us back as addVMCaller() 6700 6702 * in updateDisplayData(). */ 6701 alock. leave();6703 alock.release(); 6702 6704 6703 6705 mConsoleVRDPServer->Stop(); 6704 6706 6705 alock. enter();6707 alock.acquire(); 6706 6708 } 6707 6709 … … 6729 6731 mVMCallers)); 6730 6732 6731 alock. leave();6733 alock.release(); 6732 6734 6733 6735 RTSemEventWait(mVMZeroCallersSem, RT_INDEFINITE_WAIT); 6734 6736 6735 alock. enter();6737 alock.acquire(); 6736 6738 } 6737 6739 … … 6753 6755 { 6754 6756 LogFlowThisFunc(("Powering off the VM...\n")); 6755 alock. leave();6757 alock.release(); 6756 6758 vrc = VMR3PowerOff(VMR3GetVM(pUVM)); 6757 6759 #ifdef VBOX_WITH_EXTPACK 6758 6760 mptrExtPackManager->callAllVmPowerOffHooks(this, VMR3GetVM(pUVM)); 6759 6761 #endif 6760 alock. enter();6762 alock.acquire(); 6761 6763 } 6762 6764 … … 6772 6774 6773 6775 /* Leave the lock since EMT will call us back as addVMCaller() */ 6774 alock. leave();6776 alock.release(); 6775 6777 6776 6778 m_pVMMDev->hgcmShutdown(); 6777 6779 6778 alock. enter();6780 alock.acquire(); 6779 6781 } 6780 6782 … … 6805 6807 6806 6808 /* Now we've got to destroy the VM as well. (mpVM is not valid beyond 6807 * this point). We leave the lock before calling VMR3Destroy() because6809 * this point). We release the lock before calling VMR3Destroy() because 6808 6810 * it will result into calling destructors of drivers associated with 6809 6811 * Console children which may in turn try to lock Console (e.g. by … … 6818 6820 LogFlowThisFunc(("Destroying the VM...\n")); 6819 6821 6820 alock. leave();6822 alock.release(); 6821 6823 6822 6824 vrc = VMR3Destroy(VMR3GetVM(pUVM)); 6823 6825 6824 6826 /* take the lock again */ 6825 alock. enter();6827 alock.acquire(); 6826 6828 6827 6829 /* advance percent count */ … … 6930 6932 * UpdateState we will require Machine and SessionMachine locks 6931 6933 * (remember that here we're holding the Console lock here, and also 6932 * all locks that have been enteredby the thread before calling6934 * all locks that have been acquire by the thread before calling 6933 6935 * this method). 6934 6936 */ … … 7648 7650 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL); 7649 7651 7650 /* still want a lock object because we need to leave it */7652 /* still want a lock object because we need to release it */ 7651 7653 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 7652 7654 … … 7680 7682 Address.c_str(), uuid.raw())); 7681 7683 7682 /* leave the lock before a VMR3* call (EMT will call us back)! */7683 alock. leave();7684 /* release the lock before a VMR3* call (EMT will call us back)! */ 7685 alock.release(); 7684 7686 7685 7687 /** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */ … … 7689 7691 7690 7692 /* restore the lock */ 7691 alock. enter();7693 alock.acquire(); 7692 7694 7693 7695 /* hrc is S_OK here */ … … 7790 7792 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL); 7791 7793 7792 /* still want a lock object because we need to leave it */7794 /* still want a lock object because we need to release it */ 7793 7795 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 7794 7796 … … 7804 7806 (*aIt)->id().raw())); 7805 7807 7806 /* leave the lock before a VMR3* call (EMT will call us back)! */7807 alock. leave();7808 /* release the lock before a VMR3* call (EMT will call us back)! */ 7809 alock.release(); 7808 7810 7809 7811 /** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */ … … 8266 8268 if (RT_SUCCESS(vrc)) 8267 8269 { 8268 /* leave the lock before calling Host in VBoxSVC since Host may call8270 /* release the lock before calling Host in VBoxSVC since Host may call 8269 8271 * us back from under its lock (e.g. onUSBDeviceAttach()) which would 8270 8272 * produce an inter-process dead-lock otherwise. */ 8271 8273 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 8272 alock. leave();8274 alock.release(); 8273 8275 8274 8276 HRESULT hrc = mControl->AutoCaptureUSBDevices(); … … 8300 8302 mUSBDevices.clear(); 8301 8303 8302 /* leave the lock before calling Host in VBoxSVC since Host may call8304 /* release the lock before calling Host in VBoxSVC since Host may call 8303 8305 * us back from under its lock (e.g. onUSBDeviceAttach()) which would 8304 8306 * produce an inter-process dead-lock otherwise. */ 8305 8307 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 8306 alock. leave();8308 alock.release(); 8307 8309 8308 8310 mControl->DetachAllUSBDevices(aDone); … … 8575 8577 8576 8578 /* Does VRDP server call Console from the other thread? 8577 * Not sure (and can change), so leave the lock just in case.8579 * Not sure (and can change), so release the lock just in case. 8578 8580 */ 8579 alock. leave();8581 alock.release(); 8580 8582 vrc = server->Launch(); 8581 alock. enter();8583 alock.acquire(); 8582 8584 8583 8585 if (vrc == VERR_NET_ADDRESS_IN_USE) … … 8627 8629 PVM pVM; 8628 8630 /* 8629 * leave the lock since EMT will call Console. It's safe because8631 * release the lock since EMT will call Console. It's safe because 8630 8632 * mMachineState is either Starting or Restoring state here. 8631 8633 */ 8632 alock. leave();8634 alock.release(); 8633 8635 8634 8636 vrc = VMR3Create(cCpus, … … 8640 8642 &pVM); 8641 8643 8642 alock. enter();8644 alock.acquire(); 8643 8645 8644 8646 /* Enable client connections to the server. */ … … 8677 8679 { 8678 8680 /* Does the code below call Console from the other thread? 8679 * Not sure, so leave the lock just in case. */8680 alock. leave();8681 * Not sure, so release the lock just in case. */ 8682 alock.release(); 8681 8683 8682 8684 for (SharedFolderDataMap::const_iterator it = task->mSharedFolders.begin(); … … 8698 8700 rc = S_OK; // do not fail with broken shared folders 8699 8701 8700 /* enterthe lock again */8701 alock. enter();8702 /* acquire the lock again */ 8703 alock.acquire(); 8702 8704 } 8703 8705 … … 8708 8710 if (FAILED(rc)) break; 8709 8711 8710 /* leave the lock before a lengthy operation */8711 alock. leave();8712 /* release the lock before a lengthy operation */ 8713 alock.release(); 8712 8714 8713 8715 /* Load saved state? */ … … 8822 8824 } 8823 8825 8824 /* enterthe lock again */8825 alock. enter();8826 /* acquire the lock again */ 8827 alock.acquire(); 8826 8828 } 8827 8829 while (0); … … 8835 8837 /* powerDown() will call VMR3Destroy() and do all necessary 8836 8838 * cleanup (VRDP, USB devices) */ 8839 alock.release(); 8837 8840 HRESULT rc2 = pConsole->powerDown(); 8841 alock.acquire(); 8838 8842 AssertComRC(rc2); 8839 8843 } … … 8845 8849 * be sticky but our error callback isn't. 8846 8850 */ 8847 alock. leave();8851 alock.release(); 8848 8852 VMR3AtErrorDeregister(pVM, Console::genericVMSetErrorCallback, &task->mErrorMsg); 8849 8853 /** @todo register another VMSetError callback? */ 8850 alock. enter();8854 alock.acquire(); 8851 8855 } 8852 8856 } … … 8914 8918 */ 8915 8919 8916 /* leave the lock, don't need it any more */8917 alock. leave();8920 /* release the lock, don't need it any more */ 8921 alock.release(); 8918 8922 8919 8923 if (SUCCEEDED(rc)) … … 9114 9118 pTask->mProgress->setCancelCallback(takesnapshotProgressCancelCallback, ptrVM.rawUVM()); 9115 9119 9116 alock. leave();9120 alock.release(); 9117 9121 LogFlowFunc(("VMR3Save...\n")); 9118 9122 int vrc = VMR3Save(ptrVM, … … 9122 9126 static_cast<IProgress *>(pTask->mProgress), 9123 9127 &fSuspenededBySave); 9124 alock. enter();9128 alock.acquire(); 9125 9129 if (RT_FAILURE(vrc)) 9126 9130 throw setErrorStatic(E_FAIL, … … 9190 9194 9191 9195 /* 9192 * don't leave the lock since reconfigureMediumAttachment9196 * don't release the lock since reconfigureMediumAttachment 9193 9197 * isn't going to need the Console lock. 9194 9198 */ … … 9265 9269 LogFlowFunc(("VMR3Resume...\n")); 9266 9270 SafeVMPtr ptrVM(that); 9267 alock. leave();9271 alock.release(); 9268 9272 int vrc = VMR3Resume(ptrVM); 9269 alock. enter();9273 alock.acquire(); 9270 9274 if (RT_FAILURE(vrc)) 9271 9275 { … … 9323 9327 LogFlowFunc(("VMR3Resume (on failure)...\n")); 9324 9328 SafeVMPtr ptrVM(that); 9325 alock. leave();9329 alock.release(); 9326 9330 int vrc = VMR3Resume(ptrVM); AssertLogRelRC(vrc); 9327 alock. enter();9331 alock.acquire(); 9328 9332 if (RT_FAILURE(vrc)) 9329 9333 that->setMachineState(MachineState_Paused); … … 9411 9415 */ 9412 9416 task->releaseVMCaller(); 9417 thatLock.release(); 9413 9418 rc = that->powerDown(); 9419 thatLock.acquire(); 9414 9420 } 9415 9421 … … 9458 9464 /* release VM caller to avoid the powerDown() deadlock */ 9459 9465 task->releaseVMCaller(); 9466 9467 thatLock.release(); 9460 9468 9461 9469 that->powerDown(task->mServerProgress); -
trunk/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp
r40066 r40257 5 5 6 6 /* 7 * Copyright (C) 2010 Oracle Corporation7 * Copyright (C) 2010-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 886 886 if (pState->mfSuspendedByUs) 887 887 { 888 autoLock. leave();888 autoLock.release(); 889 889 int rc = VMR3Resume(VMR3GetVM(pState->mpUVM)); 890 890 AssertLogRelMsgRC(rc, ("VMR3Resume -> %Rrc\n", rc)); 891 autoLock. enter();891 autoLock.acquire(); 892 892 } 893 893 } … … 901 901 } 902 902 } 903 autoLock. leave();903 autoLock.release(); 904 904 905 905 /* -
trunk/src/VBox/Main/src-client/DisplayImpl.cpp
r39603 r40257 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 2038 2038 if (pVM.isOk()) 2039 2039 { 2040 /* Must leave the lock here because the changeFramebuffer will2040 /* Must release the lock here because the changeFramebuffer will 2041 2041 * also obtain it. */ 2042 alock. leave();2042 alock.release(); 2043 2043 2044 2044 /* send request to the EMT thread */ … … 2046 2046 (PFNRT) changeFramebuffer, 3, this, aFramebuffer, aScreenId); 2047 2047 2048 alock. enter();2048 alock.acquire(); 2049 2049 2050 2050 ComAssertRCRet (vrc, E_FAIL); … … 2064 2064 VMMDev *pVMMDev = mParent->getVMMDev(); 2065 2065 2066 alock. leave();2066 alock.release(); 2067 2067 2068 2068 if (pVMMDev) … … 2070 2070 /*ComAssertRCRet (vrc, E_FAIL);*/ 2071 2071 2072 alock. enter();2072 alock.acquire(); 2073 2073 } 2074 2074 } … … 2155 2155 // return setError(E_FAIL, tr("Not enough VRAM for the selected video mode")); 2156 2156 2157 /* Have to leave the lock because the pfnRequestDisplayChange2157 /* Have to release the lock because the pfnRequestDisplayChange 2158 2158 * will call EMT. */ 2159 alock. leave();2159 alock.release(); 2160 2160 2161 2161 VMMDev *pVMMDev = mParent->getVMMDev(); … … 2176 2176 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2177 2177 2178 /* Have to leave the lock because the pfnRequestSeamlessChange will call EMT. */2179 alock. leave();2178 /* Have to release the lock because the pfnRequestSeamlessChange will call EMT. */ 2179 alock.release(); 2180 2180 2181 2181 VMMDev *pVMMDev = mParent->getVMMDev(); … … 2377 2377 LogRelFlowFunc (("Sending SCREENSHOT request\n")); 2378 2378 2379 /* Leave lock because other thread (EMT) is called and it may initiate a resize2379 /* Release lock because other thread (EMT) is called and it may initiate a resize 2380 2380 * which also needs lock. 2381 2381 * 2382 2382 * This method does not need the lock anymore. 2383 2383 */ 2384 alock. leave();2384 alock.release(); 2385 2385 2386 2386 int vrc = displayTakeScreenshot(pVM, this, mpDrv, aScreenId, address, width, height); … … 2430 2430 LogRelFlowFunc (("Sending SCREENSHOT request\n")); 2431 2431 2432 /* Leave lock because other thread (EMT) is called and it may initiate a resize2432 /* Release lock because other thread (EMT) is called and it may initiate a resize 2433 2433 * which also needs lock. 2434 2434 * 2435 2435 * This method does not need the lock anymore. 2436 2436 */ 2437 alock. leave();2437 alock.release(); 2438 2438 2439 2439 size_t cbData = width * 4 * height; … … 2507 2507 LogRelFlowFunc (("Sending SCREENSHOT request\n")); 2508 2508 2509 /* Leave lock because other thread (EMT) is called and it may initiate a resize2509 /* Release lock because other thread (EMT) is called and it may initiate a resize 2510 2510 * which also needs lock. 2511 2511 * 2512 2512 * This method does not need the lock anymore. 2513 2513 */ 2514 alock. leave();2514 alock.release(); 2515 2515 2516 2516 size_t cbData = width * 4 * height; … … 2676 2676 if (FAILED(pVM.rc())) return pVM.rc(); 2677 2677 2678 /* Leave lock because the call scheduled on EMT may also try to take it. */2679 alock. leave();2678 /* Release lock because the call scheduled on EMT may also try to take it. */ 2679 alock.release(); 2680 2680 2681 2681 /* … … 2800 2800 LogRelFlowFunc (("Sending DPYUPDATE request\n")); 2801 2801 2802 /* Have to leave the lock when calling EMT. */2803 alock. leave();2802 /* Have to release the lock when calling EMT. */ 2803 alock.release(); 2804 2804 2805 2805 /* pdm.h says that this has to be called from the EMT thread */ 2806 2806 int rcVBox = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)Display::InvalidateAndUpdateEMT, 2807 2807 1, this); 2808 alock. enter();2808 alock.acquire(); 2809 2809 2810 2810 if (RT_FAILURE(rcVBox)) … … 3003 3003 3004 3004 #if defined(VBOX_WITH_CROGL) 3005 /* Leave the lock, because SHCRGL_HOST_FN_SCREEN_CHANGED will read current framebuffer */3005 /* Release the lock, because SHCRGL_HOST_FN_SCREEN_CHANGED will read current framebuffer */ 3006 3006 { 3007 3007 BOOL is3denabled; … … 3010 3010 if (is3denabled) 3011 3011 { 3012 alock. leave();3012 alock.release(); 3013 3013 } 3014 3014 } -
trunk/src/VBox/Main/src-client/SessionImpl.cpp
r40177 r40257 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 936 936 * SessionState_Closing here, so it's safe. 937 937 */ 938 alock. leave();938 alock.release(); 939 939 940 940 LogFlowThisFunc(("Calling mControl->OnSessionEnd()...\n")); … … 942 942 LogFlowThisFunc(("mControl->OnSessionEnd()=%08X\n", rc)); 943 943 944 alock. enter();944 alock.acquire(); 945 945 946 946 /* -
trunk/src/VBox/Main/src-server/BandwidthControlImpl.cpp
r35638 r40257 5 5 6 6 /* 7 * Copyright (C) 2006-20 09Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 472 472 473 473 /* inform the direct session if any */ 474 alock. leave();474 alock.release(); 475 475 //onStorageControllerChange(); @todo 476 476 -
trunk/src/VBox/Main/src-server/BandwidthGroupImpl.cpp
r35638 r40257 5 5 6 6 /* 7 * Copyright (C) 2006-20 09Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 294 294 /* inform direct session if any. */ 295 295 ComObjPtr<Machine> pMachine = m->pParent->getMachine(); 296 alock. leave();296 alock.release(); 297 297 pMachine->onBandwidthGroupChange(this); 298 298 -
trunk/src/VBox/Main/src-server/HostUSBDeviceImpl.cpp
r38213 r40257 5 5 6 6 /* 7 * Copyright (C) 2006-20 07Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 355 355 * As a convenience, this method will operate like attachToVM() if the device 356 356 * is already held by the proxy. Note that it will then perform IPC to the VM 357 * process, which means it will temporarily leave all locks. (Is this a good idea?)357 * process, which means it will temporarily release all locks. (Is this a good idea?) 358 358 * 359 359 * @param aMachine Machine this device should be attach to. … … 483 483 484 484 /* 485 * The VM process will query the object, so grab a reference to ourselves and leave the locks.485 * The VM process will query the object, so grab a reference to ourselves and release the locks. 486 486 */ 487 487 ComPtr<IUSBDevice> d = this; 488 488 489 489 AutoWriteLock alockSelf(this COMMA_LOCKVAL_SRC_POS); 490 alockSelf. leave();490 alockSelf.release(); 491 491 AutoWriteLock alockProxy(mUSBProxyService COMMA_LOCKVAL_SRC_POS); 492 alockProxy. leave();492 alockProxy.release(); 493 493 494 494 /* … … 504 504 505 505 /* 506 * As we re- enterthe lock, we'll have to check if the device was506 * As we re-acquire the lock, we'll have to check if the device was 507 507 * physically detached while we were busy. 508 508 */ 509 alockProxy. enter();510 alockSelf. enter();509 alockProxy.acquire(); 510 alockSelf.acquire(); 511 511 512 512 if (SUCCEEDED(hrc)) … … 561 561 562 562 /* 563 * Change the state and abandon dthe locks. The VM may query563 * Change the state and abandon the locks. The VM may query 564 564 * data and we don't want to deadlock - the state protects us, 565 565 * so, it's not a bit issue here. … … 567 567 setState(kHostUSBDeviceState_PhysDetachingFromVM, kHostUSBDeviceState_PhysDetached); 568 568 AutoWriteLock alockSelf(this COMMA_LOCKVAL_SRC_POS); 569 alockSelf. leave();569 alockSelf.release(); 570 570 AutoWriteLock alockProxy(mUSBProxyService COMMA_LOCKVAL_SRC_POS); 571 alockProxy. leave();571 alockProxy.release(); 572 572 573 573 /* … … 584 584 585 585 /* 586 * Re- enterthe locks and complete the transition.587 */ 588 alockProxy. enter();589 alockSelf. enter();586 * Re-acquire the locks and complete the transition. 587 */ 588 alockProxy.acquire(); 589 alockSelf.acquire(); 590 590 advanceTransition(); 591 591 } -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r40084 r40257 827 827 828 828 /* the lock is no more necessary (SessionMachine is uninitialized) */ 829 alock. leave();829 alock.release(); 830 830 831 831 // has machine been modified? … … 3064 3064 3065 3065 /* 3066 * Leave the lock before calling the client process. It's safe here3066 * Release the lock before calling the client process. It's safe here 3067 3067 * since the only thing to do after we get the lock again is to add 3068 3068 * the remote control to the list (which doesn't directly influence 3069 3069 * anything). 3070 3070 */ 3071 alock. leave();3071 alock.release(); 3072 3072 3073 3073 // get the console of the session holding the write lock (this is a remote call) … … 3092 3092 return setError(VBOX_E_VM_ERROR, 3093 3093 tr("Failed to assign the machine to the session (%Rrc)"), rc); 3094 alock. enter();3095 3096 // need to revalidate the state after entering the lock again3094 alock.acquire(); 3095 3096 // need to revalidate the state after acquiring the lock again 3097 3097 if (mData->mSession.mState != SessionState_Locked) 3098 3098 { … … 3163 3163 * Set the session state to Spawning to protect against subsequent 3164 3164 * attempts to open a session and to unregister the machine after 3165 * we leave the lock.3165 * we release the lock. 3166 3166 */ 3167 3167 SessionState_T origState = mData->mSession.mState; … … 3169 3169 3170 3170 /* 3171 * Leave the lock before calling the client process -- it will call3172 * Machine/SessionMachine methods. Leaving the lock here is quite safe3171 * Release the lock before calling the client process -- it will call 3172 * Machine/SessionMachine methods. Releasing the lock here is quite safe 3173 3173 * because the state is Spawning, so that LaunchVMProcess() and 3174 3174 * LockMachine() calls will fail. This method, called before we 3175 * enterthe lock again, will fail because of the wrong PID.3175 * acquire the lock again, will fail because of the wrong PID. 3176 3176 * 3177 3177 * Note that mData->mSession.mRemoteControls accessed outside 3178 3178 * the lock may not be modified when state is Spawning, so it's safe. 3179 3179 */ 3180 alock. leave();3180 alock.release(); 3181 3181 3182 3182 LogFlowThisFunc(("Calling AssignMachine()...\n")); … … 3227 3227 } 3228 3228 3229 /* enterthe lock again */3230 alock. enter();3229 /* acquire the lock again */ 3230 alock.acquire(); 3231 3231 3232 3232 /* Restore the session state */ … … 3283 3283 } 3284 3284 3285 /* Leave the lock since SessionMachine::uninit() locks VirtualBox which3285 /* Release the lock since SessionMachine::uninit() locks VirtualBox which 3286 3286 * would break the lock order */ 3287 alock. leave();3287 alock.release(); 3288 3288 3289 3289 /* uninitialize the created session machine on failure */ … … 3804 3804 /* Apply the normal locking logic to the entire chain. */ 3805 3805 MediumLockList *pMediumLockList(new MediumLockList()); 3806 mediumLock.release(); 3807 treeLock.release(); 3806 3808 rc = diff->createMediumLockList(true /* fFailIfInaccessible */, 3807 3809 true /* fMediumLockWrite */, 3808 3810 medium, 3809 3811 *pMediumLockList); 3812 treeLock.acquire(); 3813 mediumLock.acquire(); 3810 3814 if (SUCCEEDED(rc)) 3811 3815 { 3816 mediumLock.release(); 3817 treeLock.release(); 3812 3818 rc = pMediumLockList->Lock(); 3819 treeLock.acquire(); 3820 mediumLock.acquire(); 3813 3821 if (FAILED(rc)) 3814 3822 setError(rc, … … 3817 3825 else 3818 3826 { 3819 /* will leave the lock before the potentially lengthy operation, so3820 * protect with the special state */3827 /* will release the lock before the potentially lengthy 3828 * operation, so protect with the special state */ 3821 3829 MachineState_T oldState = mData->mMachineState; 3822 3830 setMachineState(MachineState_SettingUp); 3823 3831 3824 mediumLock. leave();3825 treeLock. leave();3826 alock. leave();3832 mediumLock.release(); 3833 treeLock.release(); 3834 alock.release(); 3827 3835 3828 3836 rc = medium->createDiffStorage(diff, … … 3833 3841 &llRegistriesThatNeedSaving); 3834 3842 3835 alock. enter();3836 treeLock. enter();3837 mediumLock. enter();3843 alock.acquire(); 3844 treeLock.acquire(); 3845 mediumLock.acquire(); 3838 3846 3839 3847 setMachineState(oldState); … … 3890 3898 3891 3899 mediumLock.release(); 3892 treeLock. leave();3900 treeLock.release(); 3893 3901 alock.release(); 3894 3902 … … 3958 3966 if (fHotplug) 3959 3967 { 3960 alock. leave();3968 alock.release(); 3961 3969 rc = onStorageDeviceChange(pAttach, TRUE /* aRemove */); 3962 alock. enter();3970 alock.acquire(); 3963 3971 } 3964 3972 if (FAILED(rc)) return rc; … … 4632 4640 // (this state combination is not supported). Note releasing the caller and 4633 4641 // leaving the lock before calling uninit() 4634 alock. leave();4642 alock.release(); 4635 4643 autoCaller.release(); 4636 4644 … … 5064 5072 5065 5073 /* inform the direct session if any */ 5066 alock. leave();5074 alock.release(); 5067 5075 onSharedFolderChange(); 5068 5076 … … 5091 5099 5092 5100 /* inform the direct session if any */ 5093 alock. leave();5101 alock.release(); 5094 5102 onSharedFolderChange(); 5095 5103 … … 5650 5658 5651 5659 /* inform the direct session if any */ 5652 alock. leave();5660 alock.release(); 5653 5661 onStorageControllerChange(); 5654 5662 … … 5744 5752 { 5745 5753 /* inform the direct session if any */ 5746 alock. leave();5754 alock.release(); 5747 5755 onStorageControllerChange(); 5748 5756 } … … 5788 5796 5789 5797 /* inform the direct session if any */ 5790 alock. leave();5798 alock.release(); 5791 5799 onStorageControllerChange(); 5792 5800 … … 6797 6805 6798 6806 /* 6799 * Note that we don't leave the lock here before calling the client,6807 * Note that we don't release the lock here before calling the client, 6800 6808 * because it doesn't need to call us back if called with a NULL argument. 6801 * Leaving the lock here is dangerous because we didn't prepare the6809 * Releasing the lock here is dangerous because we didn't prepare the 6802 6810 * launch data yet, but the client we've just started may happen to be 6803 6811 * too fast and call openSession() that will fail (because of PID, etc.), … … 7515 7523 RTSemEventMultiReset(mData->mMachineStateDepsSem); 7516 7524 7517 alock. leave();7525 alock.release(); 7518 7526 7519 7527 RTSemEventMultiWait(mData->mMachineStateDepsSem, RT_INDEFINITE_WAIT); 7520 7528 7521 alock. enter();7529 alock.acquire(); 7522 7530 7523 7531 -- mData->mMachineStateChangePending; … … 9457 9465 &mParent->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 9458 9466 9459 /* must be in a protective state because we leave the lock below */9467 /* must be in a protective state because we release the lock below */ 9460 9468 AssertReturn( mData->mMachineState == MachineState_Saving 9461 9469 || mData->mMachineState == MachineState_LiveSnapshotting … … 9490 9498 9491 9499 MediumLockList *pMediumLockList(new MediumLockList()); 9500 alock.release(); 9492 9501 rc = pMedium->createMediumLockList(true /* fFailIfInaccessible */, 9493 9502 false /* fMediumLockWrite */, 9494 9503 NULL, 9495 9504 *pMediumLockList); 9505 alock.acquire(); 9496 9506 if (FAILED(rc)) 9497 9507 { … … 9509 9519 9510 9520 /* Now lock all media. If this fails, nothing is locked. */ 9521 alock.release(); 9511 9522 rc = lockedMediaMap->Lock(); 9523 alock.acquire(); 9512 9524 if (FAILED(rc)) 9513 9525 { … … 9583 9595 9584 9596 /** @todo r=bird: How is the locking and diff image cleaned up if we fail before 9585 * the push_back? Looks like we're going to leave medium with the9597 * the push_back? Looks like we're going to release medium with the 9586 9598 * wrong kind of lock (general issue with if we fail anywhere at all) 9587 9599 * and an orphaned VDI in the snapshots folder. */ … … 9593 9605 if (aOnline) 9594 9606 { 9607 alock.release(); 9595 9608 rc = pMediumLockList->Update(pMedium, false); 9609 alock.acquire(); 9596 9610 AssertComRCThrowRC(rc); 9597 9611 } 9598 9612 9599 /* leave the locks before the potentially lengthy operation */9613 /* release the locks before the potentially lengthy operation */ 9600 9614 alock.release(); 9601 9615 rc = pMedium->createDiffStorage(diff, MediumVariant_Standard, … … 9609 9623 rc = lockedMediaMap->Unlock(); 9610 9624 AssertComRCThrowRC(rc); 9625 alock.release(); 9611 9626 rc = pMediumLockList->Append(diff, true); 9627 alock.acquire(); 9612 9628 AssertComRCThrowRC(rc); 9629 alock.release(); 9613 9630 rc = lockedMediaMap->Lock(); 9631 alock.acquire(); 9614 9632 AssertComRCThrowRC(rc); 9615 9633 … … 9654 9672 MultiResult mrc = rc; 9655 9673 9674 alock.release(); 9656 9675 mrc = deleteImplicitDiffs(pllRegistriesThatNeedSaving); 9657 9676 } … … 9726 9745 if (implicitAtts.size() != 0) 9727 9746 { 9728 /* will leave the lock before the potentially lengthy9747 /* will release the lock before the potentially lengthy 9729 9748 * operation, so protect with the special state (unless already 9730 9749 * protected) */ … … 9739 9758 setMachineState(MachineState_SettingUp); 9740 9759 9741 alock. leave();9760 alock.release(); 9742 9761 9743 9762 for (MediaData::AttachmentList::const_iterator it = implicitAtts.begin(); … … 9754 9773 } 9755 9774 9756 alock. enter();9775 alock.acquire(); 9757 9776 9758 9777 if (mData->mMachineState == MachineState_SettingUp) … … 9869 9888 /* attempt to implicitly delete the implicitly created diff */ 9870 9889 9871 9872 9873 9890 /// @todo move the implicit flag from MediumAttachment to Medium 9891 /// and forbid any hard disk operation when it is implicit. Or maybe 9892 /// a special media state for it to make it even more simple. 9874 9893 9875 9894 Assert(mMediaData.isBackedUp()); 9876 9895 9877 /* will leave the lock before the potentially lengthy operation, so9878 9896 /* will release the lock before the potentially lengthy operation, so 9897 * protect with the special state */ 9879 9898 MachineState_T oldState = mData->mMachineState; 9880 9899 setMachineState(MachineState_SettingUp); … … 10390 10409 ComObjPtr<Machine> that = this; 10391 10410 uint32_t flModifications = mData->flModifications; 10392 alock. leave();10411 alock.release(); 10393 10412 10394 10413 if (flModifications & IsModified_SharedFolders) … … 11258 11277 mData.free(); 11259 11278 11260 #if 1 /** @todo Please review this change! (bird) */ 11261 /* drop the exclusive lock before setting the below two to NULL */ 11279 /* release the exclusive lock before setting the below two to NULL */ 11262 11280 multilock.release(); 11263 #else11264 /* leave the exclusive lock before setting the below two to NULL */11265 multilock.leave();11266 #endif11267 11281 11268 11282 unconst(mParent) = NULL; … … 11990 12004 ) 11991 12005 { 11992 alock. leave();12006 alock.release(); 11993 12007 11994 12008 mParent->onGuestPropertyChange(mData->mUuid, … … 12727 12741 bool fIsVitalImage = (devType == DeviceType_HardDisk); 12728 12742 12743 alock.release(); 12729 12744 mrc = pMedium->createMediumLockList(fIsVitalImage /* fFailIfInaccessible */, 12730 12745 !fIsReadOnlyLock /* fMediumLockWrite */, 12731 12746 NULL, 12732 12747 *pMediumLockList); 12748 alock.acquire(); 12733 12749 if (FAILED(mrc)) 12734 12750 { … … 12752 12768 { 12753 12769 /* Now lock all media. If this fails, nothing is locked. */ 12770 alock.release(); 12754 12771 HRESULT rc = mData->mSession.mLockedMedia.Lock(); 12772 alock.acquire(); 12755 12773 if (FAILED(rc)) 12756 12774 { -
trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp
r39926 r40257 5 5 6 6 /* 7 * Copyright (C) 2011 Oracle Corporation7 * Copyright (C) 2011-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 649 649 try 650 650 { 651 Bstr bstrSrcId; 652 rc = pParent->COMGETTER(Id)(bstrSrcId.asOutParam()); 653 if (FAILED(rc)) throw rc; 651 // check validity of parent object 652 { 653 AutoReadLock alock(pParent COMMA_LOCKVAL_SRC_POS); 654 Bstr bstrSrcId; 655 rc = pParent->COMGETTER(Id)(bstrSrcId.asOutParam()); 656 if (FAILED(rc)) throw rc; 657 } 654 658 ComObjPtr<Medium> diff; 655 659 diff.createObject(); … … 661 665 if (FAILED(rc)) throw rc; 662 666 663 // need tree lock for createMediumLockList664 AutoWriteLock treeLock(p->getVirtualBox()->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);665 666 667 MediumLockList *pMediumLockList(new MediumLockList()); 667 668 rc = diff->createMediumLockList(true /* fFailIfInaccessible */, … … 672 673 rc = pMediumLockList->Lock(); 673 674 if (FAILED(rc)) throw rc; 674 675 treeLock.release();676 675 677 676 /* this already registers the new diff image */ … … 1202 1201 { 1203 1202 AutoWriteLock tlock(p->mParent->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 1204 rc = p->mParent->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */); 1203 rc = p->mParent->registerMedium(pTarget, &pTarget, 1204 DeviceType_HardDisk, 1205 NULL /* pllRegistriesThatNeedSaving */); 1205 1206 if (FAILED(rc)) throw rc; 1206 1207 } -
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r39799 r40257 5 5 6 6 /* 7 * Copyright (C) 2008-201 1Oracle Corporation7 * Copyright (C) 2008-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 125 125 MediumState_T preLockState; 126 126 127 /** Special synchronization for operations which must wait for queryInfo()128 * in another thread to complete. Using a SemRW is not quite ideal, but at129 * least it is subject to the lock validator, unlike the SemEventMulti130 * which we had here for many years. Catching possible deadlocks is more131 * important than a tiny bit of efficiency. */127 /** Special synchronization for operations which must wait for 128 * Medium::queryInfo in another thread to complete. Using a SemRW is 129 * not quite ideal, but at least it is subject to the lock validator, 130 * unlike the SemEventMulti which we had here for many years. Catching 131 * possible deadlocks is more important than a tiny bit of efficiency. */ 132 132 RWLockHandle queryInfoSem; 133 133 bool queryInfoRunning : 1; … … 144 144 bool autoReset : 1; 145 145 146 /** New UUID to be set on the next queryInfo()call. */146 /** New UUID to be set on the next Medium::queryInfo call. */ 147 147 const Guid uuidImage; 148 /** New parent UUID to be set on the next queryInfo()call. */148 /** New parent UUID to be set on the next Medium::queryInfo call. */ 149 149 const Guid uuidParentImage; 150 150 … … 956 956 m->hostDrive = false; 957 957 958 /* No storage unit is created yet, no need to queryInfo()*/958 /* No storage unit is created yet, no need to call Medium::queryInfo */ 959 959 960 960 rc = setFormat(aFormat); … … 978 978 979 979 AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 980 rc = m->pVirtualBox->registerHardDisk(this, pllRegistriesThatNeedSaving); 980 ComObjPtr<Medium> pMedium; 981 rc = m->pVirtualBox->registerMedium(this, &pMedium, DeviceType_HardDisk, 982 pllRegistriesThatNeedSaving); 983 Assert(this == pMedium); 981 984 } 982 985 … … 1054 1057 unconst(m->uuidImage).create(); 1055 1058 1056 { 1057 // Medium::queryInfo needs write lock 1058 AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 1059 rc = queryInfo(fForceNewUuid /* fSetImageId */, false /* fSetParentId */); 1060 } 1059 rc = queryInfo(fForceNewUuid /* fSetImageId */, false /* fSetParentId */); 1061 1060 1062 1061 if (SUCCEEDED(rc)) … … 1073 1072 AssertReturn(!m->id.isEmpty(), E_FAIL); 1074 1073 1075 /* storage format must be detected by queryInfo() if the medium is accessible */ 1074 /* storage format must be detected by Medium::queryInfo if the 1075 * medium is accessible */ 1076 1076 AssertReturn(!m->strFormat.isEmpty(), E_FAIL); 1077 1077 } … … 1134 1134 } 1135 1135 1136 /* see below why we don't call queryInfo() (and therefore treat the medium1137 * as inaccessible for now */1136 /* see below why we don't call Medium::queryInfo (and therefore treat 1137 * the medium as inaccessible for now */ 1138 1138 m->state = MediumState_Inaccessible; 1139 1139 m->strLastAccessError = tr("Accessibility check was not yet performed"); … … 1230 1230 m->strLocationFull.c_str(), m->strFormat.c_str(), m->id.raw())); 1231 1231 1232 /* Don't call queryInfo()for registered media to prevent the calling1232 /* Don't call Medium::queryInfo for registered media to prevent the calling 1233 1233 * thread (i.e. the VirtualBox server startup thread) from an unexpected 1234 1234 * freeze but mark it as initially inaccessible instead. The vital UUID, … … 1256 1256 if (FAILED(rc)) break; 1257 1257 1258 rc = m->pVirtualBox->registerHardDisk(pHD, NULL /* pllRegistriesThatNeedSaving */ ); 1258 rc = m->pVirtualBox->registerMedium(pHD, &pHD, DeviceType_HardDisk, 1259 NULL /* pllRegistriesThatNeedSaving */ ); 1259 1260 if (FAILED(rc)) break; 1260 1261 } … … 1335 1336 * @note All children of this medium get uninitialized by calling their 1336 1337 * uninit() methods. 1337 *1338 * @note Caller must hold the tree lock of the medium tree this medium is on.1339 1338 */ 1340 1339 void Medium::uninit() … … 1632 1631 1633 1632 // we access mParent and members 1634 Auto MultiWriteLock2 mlock(&m->pVirtualBox->getMediaTreeLockHandle(),1635 this->lockHandle()COMMA_LOCKVAL_SRC_POS);1633 AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 1634 AutoWriteLock mlock(this COMMA_LOCKVAL_SRC_POS); 1636 1635 1637 1636 switch (m->state) … … 1707 1706 if (aType == MediumType_Shareable) 1708 1707 { 1709 if (m->state == MediumState_Inaccessible)1710 {1711 HRESULT rc = queryInfo(false /* fSetImageId */, false /* fSetParentId */);1712 if (FAILED(rc))1713 return setError(rc,1714 tr("Cannot change type for medium '%s' to 'Shareable' because the medium is inaccessible"),1715 m->strLocationFull.c_str());1716 }1717 1718 1708 MediumVariant_T variant = getVariant(); 1719 1709 if (!(variant & MediumVariant_Fixed)) … … 1762 1752 addToRegistryIDList(llRegistriesThatNeedSaving); 1763 1753 mlock.release(); 1754 treeLock.release(); 1764 1755 HRESULT rc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving); 1765 1756 … … 1964 1955 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1965 1956 1966 AutoMultiWriteLock2 alock(&m->pVirtualBox->getMediaTreeLockHandle(), 1967 this->lockHandle() COMMA_LOCKVAL_SRC_POS); 1957 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1968 1958 1969 1959 switch (m->state) … … 1998 1988 unconst(m->uuidParentImage) = parentId; 1999 1989 1990 // must not hold any locks before calling Medium::queryInfo 1991 alock.release(); 1992 2000 1993 HRESULT rc = queryInfo(!!aSetImageId /* fSetImageId */, 2001 1994 !!aSetParentId /* fSetParentId */); … … 2011 2004 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2012 2005 2013 /* queryInfo() locks this for writing. */ 2014 AutoMultiWriteLock2 alock(&m->pVirtualBox->getMediaTreeLockHandle(), 2015 this->lockHandle() COMMA_LOCKVAL_SRC_POS); 2006 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 2016 2007 2017 2008 HRESULT rc = S_OK; … … 2023 2014 case MediumState_LockedRead: 2024 2015 { 2016 // must not hold any locks before calling Medium::queryInfo 2017 alock.release(); 2018 2025 2019 rc = queryInfo(false /* fSetImageId */, false /* fSetParentId */); 2020 2021 alock.acquire(); 2026 2022 break; 2027 2023 } … … 2095 2091 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2096 2092 2097 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2098 2099 /* Wait for a concurrently running queryInfo() to complete */ 2100 while (m->queryInfoRunning) 2101 { 2102 alock.leave(); 2103 { 2104 AutoReadLock qlock(m->queryInfoSem COMMA_LOCKVAL_SRC_POS); 2105 } 2106 alock.enter(); 2107 } 2108 2109 /* return the current state before */ 2110 if (aState) 2111 *aState = m->state; 2112 2113 HRESULT rc = S_OK; 2114 2115 switch (m->state) 2116 { 2117 case MediumState_Created: 2118 case MediumState_Inaccessible: 2119 case MediumState_LockedRead: 2120 { 2121 ++m->readers; 2122 2123 ComAssertMsgBreak(m->readers != 0, ("Counter overflow"), rc = E_FAIL); 2124 2125 /* Remember pre-lock state */ 2126 if (m->state != MediumState_LockedRead) 2127 m->preLockState = m->state; 2128 2129 LogFlowThisFunc(("Okay - prev state=%d readers=%d\n", m->state, m->readers)); 2130 m->state = MediumState_LockedRead; 2131 2132 break; 2133 } 2134 default: 2135 { 2136 LogFlowThisFunc(("Failing - state=%d\n", m->state)); 2137 rc = setStateError(); 2138 break; 2139 } 2140 } 2141 2142 return rc; 2093 return lockRead(aState, false /* fWithinQueryInfo */); 2143 2094 } 2144 2095 … … 2160 2111 case MediumState_LockedRead: 2161 2112 { 2162 Assert(m->readers != 0);2113 ComAssertMsgBreak(m->readers != 0, ("Counter underflow"), rc = E_FAIL); 2163 2114 --m->readers; 2164 2115 … … 2203 2154 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2204 2155 2205 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2206 2207 /* Wait for a concurrently running queryInfo() to complete */ 2208 while (m->queryInfoRunning) 2209 { 2210 alock.leave(); 2211 { 2212 AutoReadLock qlock(m->queryInfoSem COMMA_LOCKVAL_SRC_POS); 2213 } 2214 alock.enter(); 2215 } 2216 2217 /* return the current state before */ 2218 if (aState) 2219 *aState = m->state; 2220 2221 HRESULT rc = S_OK; 2222 2223 switch (m->state) 2224 { 2225 case MediumState_Created: 2226 case MediumState_Inaccessible: 2227 { 2228 m->preLockState = m->state; 2229 2230 LogFlowThisFunc(("Okay - prev state=%d locationFull=%s\n", m->state, getLocationFull().c_str())); 2231 m->state = MediumState_LockedWrite; 2232 break; 2233 } 2234 default: 2235 { 2236 LogFlowThisFunc(("Failing - state=%d locationFull=%s\n", m->state, getLocationFull().c_str())); 2237 rc = setStateError(); 2238 break; 2239 } 2240 } 2241 2242 return rc; 2156 return lockWrite(aState, false /* fWithinQueryInfo */); 2243 2157 } 2244 2158 … … 2557 2471 /* Apply the normal locking logic to the entire chain. */ 2558 2472 MediumLockList *pMediumLockList(new MediumLockList()); 2473 alock.release(); 2559 2474 HRESULT rc = diff->createMediumLockList(true /* fFailIfInaccessible */, 2560 2475 true /* fMediumLockWrite */, 2561 2476 this, 2562 2477 *pMediumLockList); 2478 alock.acquire(); 2563 2479 if (FAILED(rc)) 2564 2480 { … … 2567 2483 } 2568 2484 2485 alock.release(); 2569 2486 rc = pMediumLockList->Lock(); 2487 alock.acquire(); 2570 2488 if (FAILED(rc)) 2571 2489 { … … 2675 2593 /* Build the source lock list. */ 2676 2594 MediumLockList *pSourceMediumLockList(new MediumLockList()); 2595 alock.release(); 2677 2596 rc = createMediumLockList(true /* fFailIfInaccessible */, 2678 2597 false /* fMediumLockWrite */, 2679 2598 NULL, 2680 2599 *pSourceMediumLockList); 2600 alock.acquire(); 2681 2601 if (FAILED(rc)) 2682 2602 { … … 2687 2607 /* Build the target lock list (including the to-be parent chain). */ 2688 2608 MediumLockList *pTargetMediumLockList(new MediumLockList()); 2609 alock.release(); 2689 2610 rc = pTarget->createMediumLockList(true /* fFailIfInaccessible */, 2690 2611 true /* fMediumLockWrite */, 2691 2612 pParent, 2692 2613 *pTargetMediumLockList); 2614 alock.acquire(); 2693 2615 if (FAILED(rc)) 2694 2616 { … … 2698 2620 } 2699 2621 2622 alock.release(); 2700 2623 rc = pSourceMediumLockList->Lock(); 2624 alock.acquire(); 2701 2625 if (FAILED(rc)) 2702 2626 { … … 2707 2631 getLocationFull().c_str()); 2708 2632 } 2633 alock.release(); 2709 2634 rc = pTargetMediumLockList->Lock(); 2635 alock.acquire(); 2710 2636 if (FAILED(rc)) 2711 2637 { … … 2770 2696 try 2771 2697 { 2772 /* We need to lock both the current object, and the tree lock (would 2773 * cause a lock order violation otherwise) for createMediumLockList. */ 2774 AutoMultiWriteLock2 multilock(&m->pVirtualBox->getMediaTreeLockHandle(), 2775 this->lockHandle() 2776 COMMA_LOCKVAL_SRC_POS); 2698 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2777 2699 2778 2700 /* Build the medium lock list. */ 2779 2701 MediumLockList *pMediumLockList(new MediumLockList()); 2702 alock.release(); 2780 2703 rc = createMediumLockList(true /* fFailIfInaccessible */ , 2781 2704 true /* fMediumLockWrite */, 2782 2705 NULL, 2783 2706 *pMediumLockList); 2707 alock.acquire(); 2784 2708 if (FAILED(rc)) 2785 2709 { … … 2788 2712 } 2789 2713 2714 alock.release(); 2790 2715 rc = pMediumLockList->Lock(); 2716 alock.acquire(); 2791 2717 if (FAILED(rc)) 2792 2718 { … … 2843 2769 try 2844 2770 { 2845 /* We need to lock both the current object, and the tree lock (would 2846 * cause a lock order violation otherwise) for createMediumLockList. */ 2847 AutoMultiWriteLock2 multilock(&m->pVirtualBox->getMediaTreeLockHandle(), 2848 this->lockHandle() 2849 COMMA_LOCKVAL_SRC_POS); 2771 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 2850 2772 2851 2773 /* Build the medium lock list. */ 2852 2774 MediumLockList *pMediumLockList(new MediumLockList()); 2775 alock.release(); 2853 2776 rc = createMediumLockList(true /* fFailIfInaccessible */ , 2854 2777 true /* fMediumLockWrite */, 2855 2778 NULL, 2856 2779 *pMediumLockList); 2780 alock.acquire(); 2857 2781 if (FAILED(rc)) 2858 2782 { … … 2861 2785 } 2862 2786 2787 alock.release(); 2863 2788 rc = pMediumLockList->Lock(); 2789 alock.acquire(); 2864 2790 if (FAILED(rc)) 2865 2791 { … … 2934 2860 /* Build the medium lock list. */ 2935 2861 MediumLockList *pMediumLockList(new MediumLockList()); 2862 multilock.release(); 2936 2863 rc = createMediumLockList(true /* fFailIfInaccessible */, 2937 2864 true /* fMediumLockWrite */, 2938 2865 NULL, 2939 2866 *pMediumLockList); 2867 multilock.acquire(); 2940 2868 if (FAILED(rc)) 2941 2869 { … … 2944 2872 } 2945 2873 2946 /* Temporary leave this lock, cause IMedium::LockWrite, will wait for 2947 * an running IMedium::queryInfo. If there is one running it might be 2948 * it tries to acquire a MediaTreeLock as well -> dead-lock. */ 2949 multilock.leave(); 2874 multilock.release(); 2950 2875 rc = pMediumLockList->Lock(); 2951 multilock. enter();2876 multilock.acquire(); 2952 2877 if (FAILED(rc)) 2953 2878 { … … 3775 3700 * Constructs a medium lock list for this medium. The lock is not taken. 3776 3701 * 3777 * @note Caller must lock the medium tree for writing.3702 * @note Caller MUST NOT hold the media tree or medium lock. 3778 3703 * 3779 3704 * @param fFailIfInaccessible If true, this fails with an error if a medium is inaccessible. If false, … … 3789 3714 MediumLockList &mediumLockList) 3790 3715 { 3791 // Medium::queryInfo needs write lock3792 Assert( m->pVirtualBox->getMediaTreeLockHandle().isWriteLockOnCurrentThread());3716 Assert(!m->pVirtualBox->getMediaTreeLockHandle().isWriteLockOnCurrentThread()); 3717 Assert(!isWriteLockOnCurrentThread()); 3793 3718 3794 3719 AutoCaller autoCaller(this); … … 3811 3736 while (!pMedium.isNull()) 3812 3737 { 3813 // need write lock for queryInfo if medium is inaccessible 3814 AutoWriteLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 3738 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 3815 3739 3816 3740 /* Accessibility check must be first, otherwise locking interferes … … 3820 3744 if (mediumState == MediumState_Inaccessible) 3821 3745 { 3746 alock.release(); 3822 3747 rc = pMedium->queryInfo(false /* fSetImageId */, false /* fSetParentId */); 3748 alock.acquire(); 3823 3749 if (FAILED(rc)) return rc; 3824 3750 … … 4081 4007 } 4082 4008 4083 // leave the AutoCaller, as otherwise uninit() will simply hang4009 // release the AutoCaller, as otherwise uninit() will simply hang 4084 4010 autoCaller.release(); 4085 4011 … … 4200 4126 /* Build the medium lock list. */ 4201 4127 MediumLockList *pMediumLockList(new MediumLockList()); 4128 multilock.release(); 4202 4129 rc = createMediumLockList(true /* fFailIfInaccessible */, 4203 4130 true /* fMediumLockWrite */, 4204 4131 NULL, 4205 4132 *pMediumLockList); 4133 multilock.acquire(); 4206 4134 if (FAILED(rc)) 4207 4135 { … … 4210 4138 } 4211 4139 4140 multilock.release(); 4212 4141 rc = pMediumLockList->Lock(); 4142 multilock.acquire(); 4213 4143 if (FAILED(rc)) 4214 4144 { … … 4292 4222 HRESULT Medium::markForDeletion() 4293 4223 { 4294 ComAssertRet( this->lockHandle()->isWriteLockOnCurrentThread(), E_FAIL);4224 ComAssertRet(isWriteLockOnCurrentThread(), E_FAIL); 4295 4225 switch (m->state) 4296 4226 { … … 4312 4242 HRESULT Medium::unmarkForDeletion() 4313 4243 { 4314 ComAssertRet( this->lockHandle()->isWriteLockOnCurrentThread(), E_FAIL);4244 ComAssertRet(isWriteLockOnCurrentThread(), E_FAIL); 4315 4245 switch (m->state) 4316 4246 { … … 4330 4260 HRESULT Medium::markLockedForDeletion() 4331 4261 { 4332 ComAssertRet( this->lockHandle()->isWriteLockOnCurrentThread(), E_FAIL);4262 ComAssertRet(isWriteLockOnCurrentThread(), E_FAIL); 4333 4263 if ( ( m->state == MediumState_LockedRead 4334 4264 || m->state == MediumState_LockedWrite) … … 4349 4279 HRESULT Medium::unmarkLockedForDeletion() 4350 4280 { 4351 ComAssertRet( this->lockHandle()->isWriteLockOnCurrentThread(), E_FAIL);4281 ComAssertRet(isWriteLockOnCurrentThread(), E_FAIL); 4352 4282 if ( ( m->state == MediumState_LockedRead 4353 4283 || m->state == MediumState_LockedWrite) … … 4448 4378 /* Build the lock list. */ 4449 4379 aMediumLockList = new MediumLockList(); 4380 treeLock.release(); 4450 4381 if (fMergeForward) 4451 4382 rc = pTarget->createMediumLockList(true /* fFailIfInaccessible */, … … 4458 4389 NULL, 4459 4390 *aMediumLockList); 4391 treeLock.acquire(); 4460 4392 if (FAILED(rc)) 4461 4393 throw rc; … … 4554 4486 4555 4487 /* Update medium states appropriately */ 4556 if (m->state == MediumState_Created) 4557 { 4558 rc = markForDeletion(); 4559 if (FAILED(rc)) 4560 throw rc; 4561 } 4562 else 4563 { 4564 if (fLockMedia) 4565 throw setStateError(); 4566 else if ( m->state == MediumState_LockedWrite 4567 || m->state == MediumState_LockedRead) 4488 { 4489 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 4490 4491 if (m->state == MediumState_Created) 4568 4492 { 4569 /* Either mark it for deletion in locked state or allow 4570 * others to have done so. */ 4571 if (m->preLockState == MediumState_Created) 4572 markLockedForDeletion(); 4573 else if (m->preLockState != MediumState_Deleting) 4493 rc = markForDeletion(); 4494 if (FAILED(rc)) 4495 throw rc; 4496 } 4497 else 4498 { 4499 if (fLockMedia) 4500 throw setStateError(); 4501 else if ( m->state == MediumState_LockedWrite 4502 || m->state == MediumState_LockedRead) 4503 { 4504 /* Either mark it for deletion in locked state or allow 4505 * others to have done so. */ 4506 if (m->preLockState == MediumState_Created) 4507 markLockedForDeletion(); 4508 else if (m->preLockState != MediumState_Deleting) 4509 throw setStateError(); 4510 } 4511 else 4574 4512 throw setStateError(); 4575 4513 } 4576 else4577 throw setStateError();4578 4514 } 4579 4515 … … 4581 4517 { 4582 4518 /* we will need parent to reparent target */ 4583 pParentForTarget = m->pParent;4519 pParentForTarget = getParent(); 4584 4520 } 4585 4521 else … … 4641 4577 if (fLockMedia) 4642 4578 { 4579 treeLock.release(); 4643 4580 rc = aMediumLockList->Lock(); 4581 treeLock.acquire(); 4644 4582 if (FAILED(rc)) 4645 4583 { … … 4885 4823 HRESULT Medium::fixParentUuidOfChildren(const MediaList &childrenToReparent) 4886 4824 { 4825 Assert(!isWriteLockOnCurrentThread()); 4826 Assert(!m->pVirtualBox->getMediaTreeLockHandle().isWriteLockOnCurrentThread()); 4887 4827 MediumLockList mediumLockList; 4888 4828 HRESULT rc = createMediumLockList(true /* fFailIfInaccessible */, … … 4994 4934 try 4995 4935 { 4996 // locking: we need the tree lock first because we access parent pointers 4997 // and we need to write-lock the media involved 4998 AutoMultiWriteLock2 alock(&m->pVirtualBox->getMediaTreeLockHandle(), 4999 this->lockHandle() COMMA_LOCKVAL_SRC_POS); 4936 // This needs no extra locks besides what is done in the called methods. 5000 4937 5001 4938 /* Build the source lock list. */ … … 5091 5028 /* Build the target lock list. */ 5092 5029 MediumLockList *pTargetMediumLockList(new MediumLockList()); 5030 alock.release(); 5093 5031 rc = createMediumLockList(true /* fFailIfInaccessible */, 5094 5032 true /* fMediumLockWrite */, 5095 5033 aParent, 5096 5034 *pTargetMediumLockList); 5035 alock.acquire(); 5097 5036 if (FAILED(rc)) 5098 5037 { … … 5101 5040 } 5102 5041 5042 alock.release(); 5103 5043 rc = pTargetMediumLockList->Lock(); 5044 alock.acquire(); 5104 5045 if (FAILED(rc)) 5105 5046 { … … 5186 5127 /* Build the source lock list. */ 5187 5128 MediumLockList *pSourceMediumLockList(new MediumLockList()); 5129 alock.release(); 5188 5130 rc = createMediumLockList(true /* fFailIfInaccessible */, 5189 5131 false /* fMediumLockWrite */, 5190 5132 NULL, 5191 5133 *pSourceMediumLockList); 5134 alock.acquire(); 5192 5135 if (FAILED(rc)) 5193 5136 { … … 5198 5141 /* Build the target lock list (including the to-be parent chain). */ 5199 5142 MediumLockList *pTargetMediumLockList(new MediumLockList()); 5143 alock.release(); 5200 5144 rc = aTarget->createMediumLockList(true /* fFailIfInaccessible */, 5201 5145 true /* fMediumLockWrite */, 5202 5146 aParent, 5203 5147 *pTargetMediumLockList); 5148 alock.acquire(); 5204 5149 if (FAILED(rc)) 5205 5150 { … … 5209 5154 } 5210 5155 5156 alock.release(); 5211 5157 rc = pSourceMediumLockList->Lock(); 5158 alock.acquire(); 5212 5159 if (FAILED(rc)) 5213 5160 { … … 5218 5165 getLocationFull().c_str()); 5219 5166 } 5167 alock.release(); 5220 5168 rc = pTargetMediumLockList->Lock(); 5169 alock.acquire(); 5221 5170 if (FAILED(rc)) 5222 5171 { … … 5276 5225 5277 5226 /** 5227 * @note @a aState may be NULL if the state value is not needed (only for 5228 * in-process calls). 5229 */ 5230 HRESULT Medium::lockRead(MediumState_T *aState, bool fWithinQueryInfo) 5231 { 5232 /* Must not hold the object lock, as we need control over it below. */ 5233 Assert(!isWriteLockOnCurrentThread()); 5234 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 5235 5236 /* Wait for a concurrently running Medium::queryInfo to complete. */ 5237 if (m->queryInfoRunning) 5238 { 5239 /* Must not hold the media tree lock, as Medium::queryInfo needs this 5240 * lock and thus we would run into a deadlock here. */ 5241 if (!fWithinQueryInfo) 5242 Assert(!m->pVirtualBox->getMediaTreeLockHandle().isWriteLockOnCurrentThread()); 5243 while (m->queryInfoRunning) 5244 { 5245 alock.release(); 5246 { 5247 AutoReadLock qlock(m->queryInfoSem COMMA_LOCKVAL_SRC_POS); 5248 } 5249 alock.acquire(); 5250 } 5251 } 5252 5253 /* return the current state before */ 5254 if (aState) 5255 *aState = m->state; 5256 5257 HRESULT rc = S_OK; 5258 5259 switch (m->state) 5260 { 5261 case MediumState_Created: 5262 case MediumState_Inaccessible: 5263 case MediumState_LockedRead: 5264 { 5265 ++m->readers; 5266 5267 ComAssertMsgBreak(m->readers != 0, ("Counter overflow"), rc = E_FAIL); 5268 5269 /* Remember pre-lock state */ 5270 if (m->state != MediumState_LockedRead) 5271 m->preLockState = m->state; 5272 5273 LogFlowThisFunc(("Okay - prev state=%d readers=%d\n", m->state, m->readers)); 5274 m->state = MediumState_LockedRead; 5275 5276 break; 5277 } 5278 default: 5279 { 5280 LogFlowThisFunc(("Failing - state=%d\n", m->state)); 5281 rc = setStateError(); 5282 break; 5283 } 5284 } 5285 5286 return rc; 5287 } 5288 5289 /** 5290 * @note @a aState may be NULL if the state value is not needed (only for 5291 * in-process calls). 5292 */ 5293 HRESULT Medium::lockWrite(MediumState_T *aState, bool fWithinQueryInfo) 5294 { 5295 /* Must not hold the object lock, as we need control over it below. */ 5296 Assert(!isWriteLockOnCurrentThread()); 5297 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 5298 5299 /* Wait for a concurrently running Medium::queryInfo to complete. */ 5300 if (m->queryInfoRunning) 5301 { 5302 /* Must not hold the media tree lock, as Medium::queryInfo needs this 5303 * lock and thus we would run into a deadlock here. */ 5304 if (!fWithinQueryInfo) 5305 Assert(!m->pVirtualBox->getMediaTreeLockHandle().isWriteLockOnCurrentThread()); 5306 while (m->queryInfoRunning) 5307 { 5308 alock.release(); 5309 { 5310 AutoReadLock qlock(m->queryInfoSem COMMA_LOCKVAL_SRC_POS); 5311 } 5312 alock.acquire(); 5313 } 5314 } 5315 5316 /* return the current state before */ 5317 if (aState) 5318 *aState = m->state; 5319 5320 HRESULT rc = S_OK; 5321 5322 switch (m->state) 5323 { 5324 case MediumState_Created: 5325 case MediumState_Inaccessible: 5326 { 5327 m->preLockState = m->state; 5328 5329 LogFlowThisFunc(("Okay - prev state=%d locationFull=%s\n", m->state, getLocationFull().c_str())); 5330 m->state = MediumState_LockedWrite; 5331 break; 5332 } 5333 default: 5334 { 5335 LogFlowThisFunc(("Failing - state=%d locationFull=%s\n", m->state, getLocationFull().c_str())); 5336 rc = setStateError(); 5337 break; 5338 } 5339 } 5340 5341 return rc; 5342 } 5343 5344 /** 5278 5345 * Queries information from the medium. 5279 5346 * … … 5284 5351 * accessibility. 5285 5352 * 5286 * @note Caller must hold medium tree for writing.5353 * @note Caller MUST NOT hold the media tree or medium lock. 5287 5354 * 5288 5355 * @note Locks mParent for reading. Locks this object for writing. … … 5294 5361 HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId) 5295 5362 { 5296 Assert( m->pVirtualBox->getMediaTreeLockHandle().isWriteLockOnCurrentThread());5363 Assert(!isWriteLockOnCurrentThread()); 5297 5364 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 5298 5365 … … 5315 5382 while (m->queryInfoRunning) 5316 5383 { 5317 alock. leave();5384 alock.release(); 5318 5385 { 5319 5386 AutoReadLock qlock(m->queryInfoSem COMMA_LOCKVAL_SRC_POS); 5320 5387 } 5321 alock. enter();5388 alock.acquire(); 5322 5389 } 5323 5390 5324 5391 return S_OK; 5325 5392 } 5393 5394 alock.release(); 5395 Assert(!isWriteLockOnCurrentThread()); 5396 Assert(!m->pVirtualBox->getMediaTreeLockHandle().isWriteLockOnCurrentThread()); 5397 AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 5398 alock.acquire(); 5326 5399 5327 5400 bool success = false; … … 5349 5422 5350 5423 /* Lock the medium, which makes the behavior much more consistent */ 5424 alock.release(); 5351 5425 if (uOpenFlags & (VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_SHAREABLE)) 5352 rc = LockRead(NULL);5426 rc = lockRead(NULL, true /* fWithinQueryInfo */); 5353 5427 else 5354 rc = LockWrite(NULL);5428 rc = lockWrite(NULL, true /* fWithinQueryInfo */); 5355 5429 if (FAILED(rc)) return rc; 5430 alock.acquire(); 5356 5431 5357 5432 /* Copies of the input state fields which are not read-only, … … 5373 5448 bool fRepairImageZeroParentUuid = false; 5374 5449 5375 /* leave the object lock before a lengthy operation */5450 /* release the object lock before a lengthy operation */ 5376 5451 m->queryInfoRunning = true; 5377 alock.leave(); 5452 alock.release(); 5453 treeLock.release(); 5454 Assert(!isWriteLockOnCurrentThread()); 5455 Assert(!m->pVirtualBox->getMediaTreeLockHandle().isWriteLockOnCurrentThread()); 5456 5378 5457 /* Note that taking the queryInfoSem after leaving the object lock above 5379 5458 * can lead to short spinning of the loops waiting for queryInfo() to … … 5520 5599 5521 5600 /* we set mParent & children() */ 5522 AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);5601 treeLock.acquire(); 5523 5602 5524 5603 Assert(m->pParent.isNull()); 5525 5604 m->pParent = pParent; 5526 5605 m->pParent->m->llChildren.push_back(this); 5606 5607 treeLock.release(); 5527 5608 } 5528 5609 else 5529 5610 { 5530 5611 /* we access mParent */ 5531 AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);5612 treeLock.acquire(); 5532 5613 5533 5614 /* check that parent UUIDs match. Note that there's no need … … 5573 5654 /// accessible while the diff is? Probably nothing. The 5574 5655 /// real code will detect the mismatch anyway. 5656 5657 treeLock.release(); 5575 5658 } 5576 5659 } … … 5593 5676 } 5594 5677 5595 alock.enter(); 5678 treeLock.acquire(); 5679 alock.acquire(); 5596 5680 5597 5681 if (isImport || fSetImageId) … … 5642 5726 if (FAILED(rc)) return rc; 5643 5727 5644 alock. leave();5728 alock.release(); 5645 5729 5646 5730 try … … 5677 5761 } 5678 5762 5679 alock. enter();5763 alock.acquire(); 5680 5764 5681 5765 rc = UnlockWrite(NULL); … … 5712 5796 * Unregisters this medium with mVirtualBox. Called by close() under the medium tree lock. 5713 5797 * 5714 * This calls either VirtualBox::unregisterImage or VirtualBox::unregisterHardDisk depending5715 * on the device type of this medium.5716 *5717 5798 * @param pllRegistriesThatNeedSaving Optional pointer to a list of UUIDs that will receive the registry IDs that need saving. 5718 5799 * … … 5732 5813 deparent(); 5733 5814 5734 HRESULT rc = E_FAIL; 5735 switch (m->devType) 5736 { 5737 case DeviceType_DVD: 5738 case DeviceType_Floppy: 5739 rc = m->pVirtualBox->unregisterImage(this, 5740 m->devType, 5741 pllRegistriesThatNeedSaving); 5742 break; 5743 5744 case DeviceType_HardDisk: 5745 rc = m->pVirtualBox->unregisterHardDisk(this, pllRegistriesThatNeedSaving); 5746 break; 5747 5748 default: 5749 break; 5750 } 5751 5815 HRESULT rc = m->pVirtualBox->unregisterMedium(this, pllRegistriesThatNeedSaving); 5752 5816 if (FAILED(rc)) 5753 5817 { … … 6429 6493 { 6430 6494 id.create(); 6431 /* VirtualBox::register HardDisk() will need UUID */6495 /* VirtualBox::registerMedium() will need UUID */ 6432 6496 unconst(m->id) = id; 6433 6497 } … … 6495 6559 * better than breaking media registry consistency) */ 6496 6560 AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 6497 rc = m->pVirtualBox->registerHardDisk(this, NULL /* pllRegistriesThatNeedSaving */); 6498 } 6499 6500 // reenter the lock before changing state 6561 ComObjPtr<Medium> pMedium; 6562 rc = m->pVirtualBox->registerMedium(this, &pMedium, DeviceType_HardDisk, 6563 NULL /* pllRegistriesThatNeedSaving */); 6564 Assert(this == pMedium); 6565 } 6566 6567 // re-acquire the lock before changing state 6501 6568 AutoWriteLock thisLock(this COMMA_LOCKVAL_SRC_POS); 6502 6569 … … 6558 6625 { 6559 6626 targetId.create(); 6560 /* VirtualBox::register HardDisk() will need UUID */6627 /* VirtualBox::registerMedium() will need UUID */ 6561 6628 unconst(pTarget->m->id) = targetId; 6562 6629 } … … 6672 6739 * Created state only on success (leaving an orphan file is 6673 6740 * better than breaking media registry consistency) */ 6674 mrc = m->pVirtualBox->registerHardDisk(pTarget, &llRegistriesThatNeedSaving); 6741 ComObjPtr<Medium> pMedium; 6742 mrc = m->pVirtualBox->registerMedium(pTarget, &pMedium, DeviceType_HardDisk, 6743 &llRegistriesThatNeedSaving); 6744 Assert(pTarget == pMedium); 6675 6745 6676 6746 if (FAILED(mrc)) … … 6891 6961 /* first, unregister the target since it may become a base 6892 6962 * medium which needs re-registration */ 6893 rc2 = m->pVirtualBox->unregister HardDisk(pTarget, NULL /*&fNeedsGlobalSaveSettings*/);6963 rc2 = m->pVirtualBox->unregisterMedium(pTarget, NULL /*pfNeedsGlobalSaveSettings*/); 6894 6964 AssertComRC(rc2); 6895 6965 … … 6905 6975 6906 6976 /* then, register again */ 6907 rc2 = m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */ ); 6977 ComObjPtr<Medium> pMedium; 6978 rc2 = m->pVirtualBox->registerMedium(pTarget, &pMedium, 6979 DeviceType_HardDisk, 6980 NULL /* pllRegistriesThatNeedSaving */ ); 6908 6981 AssertComRC(rc2); 6909 6982 } … … 6958 7031 } 6959 7032 6960 rc2 = pMedium->m->pVirtualBox->unregister HardDisk(pMedium,6961 7033 rc2 = pMedium->m->pVirtualBox->unregisterMedium(pMedium, 7034 NULL /*pfNeedsGlobalSaveSettings*/); 6962 7035 AssertComRC(rc2); 6963 7036 … … 7254 7327 * better than breaking media registry consistency) */ 7255 7328 eik.restore(); 7256 mrc = pParent->m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */); 7329 ComObjPtr<Medium> pMedium; 7330 mrc = pParent->m->pVirtualBox->registerMedium(pTarget, &pMedium, 7331 DeviceType_HardDisk, 7332 NULL /* pllRegistriesThatNeedSaving */); 7333 Assert(pTarget == pMedium); 7257 7334 eik.fetch(); 7258 7335 … … 7265 7342 /* just register */ 7266 7343 eik.restore(); 7267 mrc = m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */); 7344 ComObjPtr<Medium> pMedium; 7345 mrc = m->pVirtualBox->registerMedium(pTarget, &pMedium, 7346 DeviceType_HardDisk, 7347 NULL /* pllRegistriesThatNeedSaving */); 7348 Assert(pTarget == pMedium); 7268 7349 eik.fetch(); 7269 7350 } … … 8029 8110 * better than breaking media registry consistency) */ 8030 8111 eik.restore(); 8031 mrc = pParent->m->pVirtualBox->registerHardDisk(this, NULL /* llRegistriesThatNeedSaving */); 8112 ComObjPtr<Medium> pMedium; 8113 mrc = pParent->m->pVirtualBox->registerMedium(this, &pMedium, 8114 DeviceType_HardDisk, 8115 NULL /* llRegistriesThatNeedSaving */); 8116 Assert(this == pMedium); 8032 8117 eik.fetch(); 8033 8118 … … 8040 8125 /* just register */ 8041 8126 eik.restore(); 8042 mrc = m->pVirtualBox->registerHardDisk(this, NULL /* pllRegistriesThatNeedSaving */); 8127 ComObjPtr<Medium> pMedium; 8128 mrc = m->pVirtualBox->registerMedium(this, &pMedium, DeviceType_HardDisk, 8129 NULL /* pllRegistriesThatNeedSaving */); 8130 Assert(this == pMedium); 8043 8131 eik.fetch(); 8044 8132 } -
trunk/src/VBox/Main/src-server/SnapshotImpl.cpp
r39248 r40257 6 6 7 7 /* 8 * Copyright (C) 2006-201 1Oracle Corporation8 * Copyright (C) 2006-2012 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 341 341 { 342 342 m->strName = strName; 343 alock. leave(); /* Important! (child->parent locks are forbidden) */343 alock.release(); /* Important! (child->parent locks are forbidden) */ 344 344 rc = m->pMachine->onSnapshotChange(this); 345 345 } … … 374 374 { 375 375 m->strDescription = strDescription; 376 alock. leave(); /* Important! (child->parent locks are forbidden) */376 alock.release(); /* Important! (child->parent locks are forbidden) */ 377 377 rc = m->pMachine->onSnapshotChange(this); 378 378 } … … 1232 1232 HRESULT rc = mPeer->saveSettings(&fNeedsGlobalSaveSettings, 1233 1233 SaveS_Force); // we know we need saving, no need to check 1234 mlock. leave();1234 mlock.release(); 1235 1235 1236 1236 if (SUCCEEDED(rc) && fNeedsGlobalSaveSettings) … … 1834 1834 } 1835 1835 1836 /* leave the locks before the potentially lengthy operation */1836 /* release the locks before the potentially lengthy operation */ 1837 1837 snapshotLock.release(); 1838 alock. leave();1838 alock.release(); 1839 1839 1840 1840 rc = createImplicitDiffs(aTask.pProgress, … … 1845 1845 throw rc; 1846 1846 1847 alock. enter();1847 alock.acquire(); 1848 1848 snapshotLock.acquire(); 1849 1849 … … 1951 1951 1952 1952 // let go of the locks while we're deleting image files below 1953 alock. leave();1953 alock.release(); 1954 1954 // from here on we cannot roll back on failure any more 1955 1955 … … 2302 2302 { 2303 2303 /* Locking order: */ 2304 AutoMultiWriteLock3 multiLock(this->lockHandle(), // machine 2305 aTask.pSnapshot->lockHandle(), // snapshot 2306 &mParent->getMediaTreeLockHandle() // media tree 2304 AutoMultiWriteLock2 multiLock(this->lockHandle(), // machine 2305 aTask.pSnapshot->lockHandle() // snapshot 2307 2306 COMMA_LOCKVAL_SRC_POS); 2308 // once we have this lock, we know that SessionMachine::DeleteSnapshot() 2309 // has exited after setting the machine state to MachineState_DeletingSnapshot 2307 // once we have this lock, we know that SessionMachine::DeleteSnapshot() 2308 // has exited after setting the machine state to MachineState_DeletingSnapshot 2309 2310 AutoWriteLock treeLock(mParent->getMediaTreeLockHandle() 2311 COMMA_LOCKVAL_SRC_POS); 2310 2312 2311 2313 ComObjPtr<SnapshotMachine> pSnapMachine = aTask.pSnapshot->getSnapshotMachine(); … … 2384 2386 fOnlineMergePossible = false; 2385 2387 } 2388 2389 // no need to hold the lock any longer 2390 attachLock.release(); 2391 2392 treeLock.release(); 2386 2393 rc = prepareDeleteSnapshotMedium(pHD, machineId, snapshotId, 2387 2394 fOnlineMergePossible, … … 2391 2398 fNeedsOnlineMerge, 2392 2399 pMediumLockList); 2400 treeLock.acquire(); 2393 2401 if (FAILED(rc)) 2394 2402 throw rc; 2395 2396 // no need to hold the lock any longer2397 attachLock.release();2398 2403 2399 2404 // For simplicity, prepareDeleteSnapshotMedium selects the merge … … 2465 2470 } 2466 2471 2467 // we can release the lock now since the machine state is MachineState_DeletingSnapshot 2472 // we can release the locks now since the machine state is MachineState_DeletingSnapshot 2473 treeLock.release(); 2468 2474 multiLock.release(); 2469 2475 … … 2786 2792 MediumLockList * &aMediumLockList) 2787 2793 { 2788 Assert( mParent->getMediaTreeLockHandle().isWriteLockOnCurrentThread());2794 Assert(!mParent->getMediaTreeLockHandle().isWriteLockOnCurrentThread()); 2789 2795 Assert(!fOnlineMergePossible || VALID_PTR(aVMMALockList)); 2790 2796 … … 2812 2818 /* lock only, to prevent any usage until the snapshot deletion 2813 2819 * is completed */ 2820 alock.release(); 2814 2821 return aHD->LockWrite(NULL); 2815 2822 } … … 2829 2836 ComObjPtr<Medium> pChild = aHD->getChildren().front(); 2830 2837 2831 /* we keep this locked, so lock the affected child to make sure the lock2832 * order is correct when calling prepareMergeTo() */2833 2838 AutoWriteLock childLock(pChild COMMA_LOCKVAL_SRC_POS); 2834 2839 … … 2843 2848 /* backward merge is too tricky, we'll just detach on snapshot 2844 2849 * deletion, so lock only, to prevent any usage */ 2850 childLock.release(); 2851 alock.release(); 2845 2852 return aHD->LockWrite(NULL); 2846 2853 } … … 2857 2864 2858 2865 HRESULT rc; 2866 childLock.release(); 2867 alock.release(); 2859 2868 rc = aSource->prepareMergeTo(aTarget, &aMachineId, &aSnapshotId, 2860 2869 !fOnlineMergePossible /* fLockMedia */, 2861 2870 aMergeForward, aParentForTarget, 2862 2871 aChildrenToReparent, aMediumLockList); 2872 alock.acquire(); 2873 childLock.acquire(); 2863 2874 if (SUCCEEDED(rc) && fOnlineMergePossible) 2864 2875 { … … 2867 2878 * asking the VM to do the merging. Only continue with the online 2868 2879 * merging preparation if applicable. */ 2880 childLock.release(); 2881 alock.release(); 2869 2882 rc = aMediumLockList->Lock(); 2883 alock.acquire(); 2884 childLock.acquire(); 2870 2885 if (FAILED(rc) && fOnlineMergePossible) 2871 2886 { … … 2895 2910 } 2896 2911 bool fLockReq = (it2->GetLockRequest() || it->GetLockRequest()); 2912 childLock.release(); 2913 alock.release(); 2897 2914 rc = it->UpdateLock(fLockReq); 2915 alock.acquire(); 2916 childLock.acquire(); 2898 2917 if (FAILED(rc)) 2899 2918 { … … 2912 2931 { 2913 2932 ComObjPtr<Medium> pMedium = *it; 2933 AutoReadLock mediumLock(pMedium COMMA_LOCKVAL_SRC_POS); 2914 2934 if (pMedium->getState() == MediumState_Created) 2915 2935 { 2936 mediumLock.release(); 2937 childLock.release(); 2938 alock.release(); 2916 2939 rc = pMedium->LockWrite(NULL); 2940 alock.acquire(); 2941 childLock.acquire(); 2942 mediumLock.acquire(); 2917 2943 if (FAILED(rc)) 2918 2944 throw rc; … … 2920 2946 else 2921 2947 { 2948 mediumLock.release(); 2949 childLock.release(); 2950 alock.release(); 2922 2951 rc = aVMMALockList->Update(pMedium, true); 2952 alock.acquire(); 2953 childLock.acquire(); 2954 mediumLock.acquire(); 2923 2955 if (FAILED(rc)) 2924 2956 { 2957 mediumLock.release(); 2958 childLock.release(); 2959 alock.release(); 2925 2960 rc = pMedium->LockWrite(NULL); 2961 alock.acquire(); 2962 childLock.acquire(); 2963 mediumLock.acquire(); 2926 2964 if (FAILED(rc)) 2927 throw rc;2965 throw rc; 2928 2966 } 2929 2967 } … … 2933 2971 if (fOnlineMergePossible) 2934 2972 { 2973 childLock.release(); 2974 alock.release(); 2935 2975 rc = aVMMALockList->Lock(); 2976 alock.acquire(); 2977 childLock.acquire(); 2936 2978 if (FAILED(rc)) 2937 2979 { … … 2967 3009 ++it) 2968 3010 { 3011 childLock.release(); 3012 alock.release(); 2969 3013 it->UpdateLock(it == lockListLast); 3014 alock.acquire(); 3015 childLock.acquire(); 2970 3016 ComObjPtr<Medium> pMedium = it->GetMedium(); 2971 3017 AutoWriteLock mediumLock(pMedium COMMA_LOCKVAL_SRC_POS); … … 3058 3104 pMedium->unmarkLockedForDeletion(); 3059 3105 } 3106 mediumLock.release(); 3060 3107 it->UpdateLock(it == lockListLast); 3108 mediumLock.acquire(); 3061 3109 } 3062 3110 } … … 3222 3270 // first, unregister the target since it may become a base 3223 3271 // hard disk which needs re-registration 3224 rc = mParent->unregister HardDisk(pTarget, NULL /*&fNeedsGlobalSaveSettings*/);3272 rc = mParent->unregisterMedium(pTarget, NULL /*&fNeedsGlobalSaveSettings*/); 3225 3273 AssertComRC(rc); 3226 3274 … … 3233 3281 3234 3282 // then, register again 3235 rc = mParent->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */); 3283 rc = mParent->registerMedium(pTarget, &pTarget, DeviceType_HardDisk, 3284 NULL /* pllRegistriesThatNeedSaving */); 3236 3285 AssertComRC(rc); 3237 3286 } … … 3261 3310 toReparent.push_back(pMedium); 3262 3311 } 3312 treeLock.release(); 3263 3313 pTarget->fixParentUuidOfChildren(toReparent); 3314 treeLock.acquire(); 3264 3315 3265 3316 // obey {parent,child} lock order … … 3304 3355 else 3305 3356 { 3306 rc = mParent->unregisterHardDisk(pMedium, 3307 NULL /*pfNeedsGlobalSaveSettings*/); 3357 rc = mParent->unregisterMedium(pMedium, NULL /*pfNeedsGlobalSaveSettings*/); 3308 3358 AssertComRC(rc); 3309 3359 -
trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
r40205 r40257 628 628 if (FAILED(rc)) return rc; 629 629 630 rc = registerHardDisk(pHardDisk, NULL /* pllRegistriesThatNeedSaving */); 630 rc = registerMedium(pHardDisk, &pHardDisk, DeviceType_HardDisk, 631 NULL /* pllRegistriesThatNeedSaving */); 631 632 if (FAILED(rc)) return rc; 632 633 } … … 648 649 if (FAILED(rc)) return rc; 649 650 650 rc = registerImage(pImage, 651 DeviceType_DVD, 652 NULL /* pllRegistriesThatNeedSaving */); 651 rc = registerMedium(pImage, &pImage, DeviceType_DVD, 652 NULL /* pllRegistriesThatNeedSaving */); 653 653 if (FAILED(rc)) return rc; 654 654 } … … 670 670 if (FAILED(rc)) return rc; 671 671 672 rc = registerImage(pImage, 673 DeviceType_Floppy, 674 NULL /* pllRegistriesThatNeedSaving */); 672 rc = registerMedium(pImage, &pImage, DeviceType_Floppy, 673 NULL /* pllRegistriesThatNeedSaving */); 675 674 if (FAILED(rc)) return rc; 676 675 } … … 1713 1712 { 1714 1713 pMedium.createObject(); 1714 treeLock.release(); 1715 1715 rc = pMedium->init(this, 1716 1716 aLocation, … … 1718 1718 fForceNewUuid, 1719 1719 deviceType); 1720 treeLock.acquire(); 1720 1721 1721 1722 if (SUCCEEDED(rc)) 1722 1723 { 1723 switch (deviceType) 1724 { 1725 case DeviceType_HardDisk: 1726 rc = registerHardDisk(pMedium, NULL /* pllRegistriesThatNeedSaving */); 1727 break; 1728 1729 case DeviceType_DVD: 1730 case DeviceType_Floppy: 1731 rc = registerImage(pMedium, 1732 deviceType, 1733 NULL /* pllRegistriesThatNeedSaving */); 1734 break; 1735 } 1724 rc = registerMedium(pMedium, &pMedium, deviceType, 1725 NULL /* pllRegistriesThatNeedSaving */); 1736 1726 1737 1727 treeLock.release(); … … 3200 3190 * @param aLocation Location to check. 3201 3191 * @param aConflict Where to return parameters of the conflicting medium. 3192 * @param ppMedium Medium reference in case this is simply a duplicate. 3202 3193 * 3203 3194 * @note Locks the media tree and media objects for reading. … … 3206 3197 const Utf8Str &aLocation, 3207 3198 Utf8Str &aConflict, 3208 bool &fIdentical) 3209 { 3199 ComObjPtr<Medium> *ppMedium) 3200 { 3201 AssertReturn(!aId.isEmpty() && !aLocation.isEmpty(), E_FAIL); 3202 AssertReturn(!ppMedium, E_INVALIDARG); 3203 3210 3204 aConflict.setNull(); 3211 3212 AssertReturn(!aId.isEmpty() && !aLocation.isEmpty(), E_FAIL); 3205 ppMedium->setNull(); 3213 3206 3214 3207 AutoReadLock alock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 3215 3208 3216 3209 HRESULT rc = S_OK; 3217 3218 aConflict.setNull();3219 fIdentical = false;3220 3210 3221 3211 ComObjPtr<Medium> pMediumFound; … … 3254 3244 && (idFound == aId) 3255 3245 ) 3256 fIdentical = true;3246 *ppMedium = pMediumFound; 3257 3247 3258 3248 aConflict = Utf8StrFmt(tr("%s '%s' with UUID {%RTuuid}"), … … 3542 3532 3543 3533 /** 3544 * Remembers the given hard disk by storing it in either the global hard disk registry 3545 * or a machine one. 3546 * 3547 * @note Caller must hold the media tree lock for writing; in addition, this locks @a aHardDisk for reading 3548 * 3549 * @param aHardDisk Hard disk object to remember. 3550 * @param uuidMachineRegistry UUID of machine whose registry should be used, or a NULL UUID for the global registry. 3534 * Remembers the given medium object by storing it in either the global 3535 * medium registry or a machine one. 3536 * 3537 * @note Caller must hold the media tree lock for writing; in addition, this 3538 * locks @a pMedium for reading 3539 * 3540 * @param pMedium Hard disk object to remember. 3541 * @param ppMedium Actually stored hard disk object. Can be different if due 3542 * to an unavoidable race there was a duplicate Medium object 3543 * created. 3544 * @param argType Either DeviceType_DVD or DeviceType_Floppy. 3551 3545 * @param pllRegistriesThatNeedSaving Optional pointer to a list of UUIDs of media registries that need saving. 3552 3546 * @return 3553 3547 */ 3554 HRESULT VirtualBox::registerHardDisk(Medium *pMedium, 3555 GuidList *pllRegistriesThatNeedSaving) 3548 HRESULT VirtualBox::registerMedium(Medium *pMedium, 3549 ComObjPtr<Medium> *ppMedium, 3550 DeviceType_T argType, 3551 GuidList *pllRegistriesThatNeedSaving) 3556 3552 { 3557 3553 AssertReturn(pMedium != NULL, E_INVALIDARG); 3554 AssertReturn(ppMedium != NULL, E_INVALIDARG); 3558 3555 3559 3556 AutoCaller autoCaller(this); 3560 3557 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 3561 3558 3562 AutoCaller hardDiskCaller(pMedium); 3563 AssertComRCReturn(hardDiskCaller.rc(), hardDiskCaller.rc()); 3559 AutoCaller mediumCaller(pMedium); 3560 AssertComRCReturn(mediumCaller.rc(), mediumCaller.rc()); 3561 3562 const char *pszDevType = NULL; 3563 ObjectsList<Medium> *pall = NULL; 3564 switch (argType) 3565 { 3566 case DeviceType_HardDisk: 3567 pall = &m->allHardDisks; 3568 pszDevType = tr("hard disk"); 3569 break; 3570 case DeviceType_DVD: 3571 pszDevType = tr("DVD image"); 3572 pall = &m->allDVDImages; 3573 break; 3574 case DeviceType_Floppy: 3575 pszDevType = tr("floppy image"); 3576 pall = &m->allFloppyImages; 3577 break; 3578 default: 3579 AssertMsgFailedReturn(("invalid device type %d", argType), E_INVALIDARG); 3580 } 3564 3581 3565 3582 // caller must hold the media tree write lock … … 3570 3587 ComObjPtr<Medium> pParent; 3571 3588 { 3572 AutoReadLock hardDiskLock(pMedium COMMA_LOCKVAL_SRC_POS);3589 AutoReadLock mediumLock(pMedium COMMA_LOCKVAL_SRC_POS); 3573 3590 id = pMedium->getId(); 3574 3591 strLocationFull = pMedium->getLocationFull(); … … 3579 3596 3580 3597 Utf8Str strConflict; 3581 bool fIdentical;3598 ComObjPtr<Medium> pDupMedium; 3582 3599 rc = checkMediaForConflicts(id, 3583 3600 strLocationFull, 3584 3601 strConflict, 3585 fIdentical);3602 &pDupMedium); 3586 3603 if (FAILED(rc)) return rc; 3587 3604 3588 if ( !fIdentical)3605 if (pDupMedium.isNull()) 3589 3606 { 3590 3607 if (strConflict.length()) 3591 3608 return setError(E_INVALIDARG, 3592 tr("Cannot register the hard disk '%s' {%RTuuid} because a %s already exists"), 3609 tr("Cannot register the %s '%s' {%RTuuid} because a %s already exists"), 3610 pszDevType, 3593 3611 strLocationFull.c_str(), 3594 3612 id.raw(), … … 3596 3614 m->strSettingsFilePath.c_str()); 3597 3615 3598 // store base (root) hard disks in the list3616 // add to the collection if it is a base medium 3599 3617 if (pParent.isNull()) 3600 m->allHardDisks.getList().push_back(pMedium); 3601 // access the list directly because we already locked the list above 3618 pall->getList().push_back(pMedium); 3602 3619 3603 3620 // store all hard disks (even differencing images) in the map 3604 m->mapHardDisks[id] = pMedium; 3621 if (argType == DeviceType_HardDisk) 3622 m->mapHardDisks[id] = pMedium; 3605 3623 3606 3624 if (pllRegistriesThatNeedSaving) 3607 3625 pMedium->addToRegistryIDList(*pllRegistriesThatNeedSaving); 3608 3626 } 3627 else 3628 pMedium = pDupMedium; 3629 3630 *ppMedium = pMedium; 3609 3631 3610 3632 return rc; … … 3612 3634 3613 3635 /** 3614 * Removes the given hard disk from the hard diskregistry.3615 * 3616 * @param aHardDiskHard disk object to remove.3636 * Removes the given medium from the respective registry. 3637 * 3638 * @param pMedium Hard disk object to remove. 3617 3639 * @param pfNeedsGlobalSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true 3618 3640 * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. 3619 3641 * 3620 * @note Caller must hold the media tree lock for writing; in addition, this locks @a aHardDiskfor reading3621 */ 3622 HRESULT VirtualBox::unregister HardDisk(Medium *aHardDisk,3623 3624 { 3625 AssertReturn( aHardDisk!= NULL, E_INVALIDARG);3642 * @note Caller must hold the media tree lock for writing; in addition, this locks @a pMedium for reading 3643 */ 3644 HRESULT VirtualBox::unregisterMedium(Medium *pMedium, 3645 GuidList *pllRegistriesThatNeedSaving) 3646 { 3647 AssertReturn(pMedium != NULL, E_INVALIDARG); 3626 3648 3627 3649 AutoCaller autoCaller(this); 3628 3650 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 3629 3651 3630 AutoCaller hardDiskCaller(aHardDisk);3631 AssertComRCReturn( hardDiskCaller.rc(), hardDiskCaller.rc());3652 AutoCaller mediumCaller(pMedium); 3653 AssertComRCReturn(mediumCaller.rc(), mediumCaller.rc()); 3632 3654 3633 3655 // caller must hold the media tree write lock … … 3636 3658 Guid id; 3637 3659 ComObjPtr<Medium> pParent; 3638 { 3639 AutoReadLock hardDiskLock(aHardDisk COMMA_LOCKVAL_SRC_POS); 3640 id = aHardDisk->getId(); 3641 pParent = aHardDisk->getParent(); 3642 } 3643 3644 // remove base (root) hard disks from the list 3660 DeviceType_T devType; 3661 { 3662 AutoReadLock mediumLock(pMedium COMMA_LOCKVAL_SRC_POS); 3663 id = pMedium->getId(); 3664 pParent = pMedium->getParent(); 3665 devType = pMedium->getDeviceType(); 3666 } 3667 3668 ObjectsList<Medium> *pall = NULL; 3669 switch (devType) 3670 { 3671 case DeviceType_HardDisk: 3672 pall = &m->allHardDisks; 3673 break; 3674 case DeviceType_DVD: 3675 pall = &m->allDVDImages; 3676 break; 3677 case DeviceType_Floppy: 3678 pall = &m->allFloppyImages; 3679 break; 3680 default: 3681 AssertMsgFailedReturn(("invalid device type %d", devType), E_INVALIDARG); 3682 } 3683 3684 // remove from the collection if it is a base medium 3645 3685 if (pParent.isNull()) 3646 m->allHardDisks.getList().remove(aHardDisk); 3647 // access the list directly because caller must have locked the list 3686 pall->getList().remove(pMedium); 3648 3687 3649 3688 // remove all hard disks (even differencing images) from map 3650 size_t cnt = m->mapHardDisks.erase(id); 3651 Assert(cnt == 1); 3652 NOREF(cnt); 3689 if (devType == DeviceType_HardDisk) 3690 { 3691 size_t cnt = m->mapHardDisks.erase(id); 3692 Assert(cnt == 1); 3693 NOREF(cnt); 3694 } 3653 3695 3654 3696 if (pllRegistriesThatNeedSaving) 3655 aHardDisk->addToRegistryIDList(*pllRegistriesThatNeedSaving);3697 pMedium->addToRegistryIDList(*pllRegistriesThatNeedSaving); 3656 3698 3657 3699 return S_OK; 3658 }3659 3660 /**3661 * Remembers the given image by storing it in the CD/DVD or floppy image registry.3662 *3663 * @param argImage Image object to remember.3664 * @param argType Either DeviceType_DVD or DeviceType_Floppy.3665 * @param uuidMachineRegistry UUID of machine whose registry should be used, or a NULL UUID for the global registry.3666 *3667 * @note Caller must hold the media tree lock for writing; in addition, this locks @a argImage for reading3668 */3669 HRESULT VirtualBox::registerImage(Medium *pMedium,3670 DeviceType_T argType,3671 GuidList *pllRegistriesThatNeedSaving)3672 {3673 AssertReturn(pMedium != NULL, E_INVALIDARG);3674 3675 AutoCaller autoCaller(this);3676 AssertComRCReturn(autoCaller.rc(), autoCaller.rc());3677 3678 AutoCaller imageCaller(pMedium);3679 AssertComRCReturn(imageCaller.rc(), imageCaller.rc());3680 3681 // caller must hold the media tree write lock3682 Assert(getMediaTreeLockHandle().isWriteLockOnCurrentThread());3683 3684 Guid id;3685 Utf8Str strLocationFull;3686 ComObjPtr<Medium> pParent;3687 {3688 AutoReadLock al(pMedium COMMA_LOCKVAL_SRC_POS);3689 id = pMedium->getId();3690 strLocationFull = pMedium->getLocationFull();3691 pParent = pMedium->getParent();3692 }3693 3694 // work on DVDs or floppies list?3695 ObjectsList<Medium> &all = (argType == DeviceType_DVD) ? m->allDVDImages : m->allFloppyImages;3696 3697 HRESULT rc;3698 // lock the images lists (list + map) while checking for conflicts3699 AutoWriteLock al(all.getLockHandle() COMMA_LOCKVAL_SRC_POS);3700 3701 Utf8Str strConflict;3702 bool fIdentical;3703 rc = checkMediaForConflicts(id,3704 strLocationFull,3705 strConflict,3706 fIdentical);3707 if (FAILED(rc)) return rc;3708 3709 if (!fIdentical)3710 {3711 if (strConflict.length())3712 return setError(VBOX_E_INVALID_OBJECT_STATE,3713 tr("Cannot register the image '%s' with UUID {%RTuuid} because a %s already exists"),3714 strLocationFull.c_str(),3715 id.raw(),3716 strConflict.c_str());3717 3718 // add to the collection3719 all.getList().push_back(pMedium);3720 // access the list directly because we already locked the list above3721 3722 if (pllRegistriesThatNeedSaving)3723 pMedium->addToRegistryIDList(*pllRegistriesThatNeedSaving);3724 }3725 3726 return rc;3727 }3728 3729 /**3730 * Removes the given image from the CD/DVD or floppy image registry.3731 *3732 * @param argImage Image object to remove.3733 * @param argType Either DeviceType_DVD or DeviceType_Floppy.3734 * @param pfNeedsGlobalSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true3735 * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.3736 *3737 * @note Caller must hold the media tree lock for writing; in addition, this locks @a argImage for reading3738 */3739 HRESULT VirtualBox::unregisterImage(Medium *argImage,3740 DeviceType_T argType,3741 GuidList *pllRegistriesThatNeedSaving)3742 {3743 AssertReturn(argImage != NULL, E_INVALIDARG);3744 3745 AutoCaller autoCaller(this);3746 AssertComRCReturn(autoCaller.rc(), autoCaller.rc());3747 3748 AutoCaller imageCaller(argImage);3749 AssertComRCReturn(imageCaller.rc(), imageCaller.rc());3750 3751 // caller must hold the media tree write lock3752 Assert(getMediaTreeLockHandle().isWriteLockOnCurrentThread());3753 3754 Guid id;3755 ComObjPtr<Medium> pParent;3756 {3757 AutoReadLock al(argImage COMMA_LOCKVAL_SRC_POS);3758 id = argImage->getId();3759 pParent = argImage->getParent();3760 }3761 3762 // work on DVDs or floppies list?3763 ObjectsList<Medium> &all = (argType == DeviceType_DVD) ? m->allDVDImages : m->allFloppyImages;3764 3765 // access the list directly because the caller must have requested the lock3766 all.getList().remove(argImage);3767 3768 HRESULT rc = S_OK;3769 3770 if (pllRegistriesThatNeedSaving)3771 argImage->addToRegistryIDList(*pllRegistriesThatNeedSaving);3772 3773 return rc;3774 3700 } 3775 3701 … … 4742 4668 4743 4669 /** 4744 * Remembers the given dhcp server by storing it in the hard disk registry.4745 * 4746 * @param aDHCPServer Dhcp Server object to remember.4747 * @param aSave Registry @c true to save hard disk registryto disk (default).4748 * 4749 * When @a aSave Registryis @c true, this operation may fail because of the4670 * Remembers the given DHCP server in the settings. 4671 * 4672 * @param aDHCPServer DHCP server object to remember. 4673 * @param aSaveSettings @c true to save settings to disk (default). 4674 * 4675 * When @a aSaveSettings is @c true, this operation may fail because of the 4750 4676 * failed #saveSettings() method it calls. In this case, the dhcp server object 4751 4677 * will not be remembered. It is therefore the responsibility of the caller to … … 4757 4683 */ 4758 4684 HRESULT VirtualBox::registerDHCPServer(DHCPServer *aDHCPServer, 4759 bool aSave Registry/*= true*/)4685 bool aSaveSettings /*= true*/) 4760 4686 { 4761 4687 AssertReturn(aDHCPServer != NULL, E_INVALIDARG); … … 4781 4707 m->allDHCPServers.addChild(aDHCPServer); 4782 4708 4783 if (aSave Registry)4709 if (aSaveSettings) 4784 4710 { 4785 4711 AutoWriteLock vboxLock(this COMMA_LOCKVAL_SRC_POS); … … 4788 4714 4789 4715 if (FAILED(rc)) 4790 unregisterDHCPServer(aDHCPServer, false /* aSave Registry*/);4716 unregisterDHCPServer(aDHCPServer, false /* aSaveSettings */); 4791 4717 } 4792 4718 … … 4795 4721 4796 4722 /** 4797 * Removes the given hard disk from the hard disk registry. 4798 * 4799 * @param aHardDisk Hard disk object to remove. 4800 * @param aSaveRegistry @c true to save hard disk registry to disk (default). 4801 * 4802 * When @a aSaveRegistry is @c true, this operation may fail because of the 4803 * failed #saveSettings() method it calls. In this case, the hard disk object 4804 * will NOT be removed from the registry when this method returns. It is 4805 * therefore the responsibility of the caller to call this method as the first 4806 * step of some action that requires unregistration, before calling uninit() on 4807 * @a aHardDisk. 4808 * 4809 * @note Locks this object for writing and @a aHardDisk for reading. 4723 * Removes the given DHCP server from the settings. 4724 * 4725 * @param aDHCPServer DHCP server object to remove. 4726 * @param aSaveSettings @c true to save settings to disk (default). 4727 * 4728 * When @a aSaveSettings is @c true, this operation may fail because of the 4729 * failed #saveSettings() method it calls. In this case, the DHCP server 4730 * will NOT be removed from the settingsi when this method returns. 4731 * 4732 * @note Locks this object for writing. 4810 4733 */ 4811 4734 HRESULT VirtualBox::unregisterDHCPServer(DHCPServer *aDHCPServer, 4812 bool aSave Registry/*= true*/)4735 bool aSaveSettings /*= true*/) 4813 4736 { 4814 4737 AssertReturn(aDHCPServer != NULL, E_INVALIDARG); … … 4824 4747 HRESULT rc = S_OK; 4825 4748 4826 if (aSave Registry)4749 if (aSaveSettings) 4827 4750 { 4828 4751 AutoWriteLock vboxLock(this COMMA_LOCKVAL_SRC_POS); … … 4831 4754 4832 4755 if (FAILED(rc)) 4833 registerDHCPServer(aDHCPServer, false /* aSave Registry*/);4756 registerDHCPServer(aDHCPServer, false /* aSaveSettings */); 4834 4757 } 4835 4758
Note:
See TracChangeset
for help on using the changeset viewer.