MediumLock.cpp revision 76364cddabfeb143dad91862d41a5638d8860b25
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/** @file
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Medium lock management helper classes
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu/*
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Copyright (C) 2010 Oracle Corporation
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu *
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * This file is part of VirtualBox Open Source Edition (OSE), as
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * available from http://www.virtualbox.org. This file is free software;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * you can redistribute it and/or modify it under the terms of the GNU
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * General Public License (GPL) as published by the Free Software
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * Foundation, in version 2 as it comes in the "COPYING" file of the
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu */
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include "MediumLock.h"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include "MediumImpl.h"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu#include "MediumAttachmentImpl.h"
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLock::MediumLock()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu : mMedium(NULL), mMediumCaller(NULL), mLockWrite(false),
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked(false), mLockSkipped(false)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLock::~MediumLock()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu Unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLock::MediumLock(const MediumLock &aMediumLock)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu : mMedium(aMediumLock.mMedium), mMediumCaller(NULL),
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mLockWrite(aMediumLock.mLockWrite), mIsLocked(false), mLockSkipped(false)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLock::MediumLock(const ComObjPtr<Medium> &aMedium, bool aLockWrite)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu : mMedium(aMedium), mMediumCaller(NULL), mLockWrite(aLockWrite),
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked(false), mLockSkipped(false)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLock::UpdateLock(bool aLockWrite)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu bool fPrevLockWrite = mLockWrite;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mIsLocked)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu Unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mLockWrite = aLockWrite;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = Lock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (FAILED(rc))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mLockWrite = fPrevLockWrite;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu Lock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mLockWrite = aLockWrite;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liuconst ComObjPtr<Medium> &MediumLock::GetMedium() const
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return mMedium;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liubool MediumLock::GetLockRequest() const
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return mLockWrite;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLock::Lock()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mIsLocked)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumCaller.attach(mMedium);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (FAILED(mMediumCaller.rc()))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumCaller.attach(NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return VBOX_E_INVALID_OBJECT_STATE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu MediumState_T state;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu AutoReadLock alock(mMedium COMMA_LOCKVAL_SRC_POS);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu state = mMedium->getState();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu switch (state)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case MediumState_NotCreated:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case MediumState_Creating:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu case MediumState_Deleting:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mLockSkipped = true;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu default:
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mLockWrite)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = mMedium->LockWrite(NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu else
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = mMedium->LockRead(NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (SUCCEEDED(rc))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked = true;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu else
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumCaller.attach(NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return VBOX_E_INVALID_OBJECT_STATE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLock::Unlock()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mIsLocked && !mLockSkipped)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mLockWrite)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = mMedium->UnlockWrite(NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu else
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = mMedium->UnlockRead(NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumCaller.attach(NULL);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mLockSkipped = false;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked = false;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLockList::MediumLockList()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked = false;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLockList::~MediumLockList()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu Clear();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu // rest is done by the list object's destructor
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liubool MediumLockList::IsEmpty()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return mMediumLocks.empty();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockList::Append(const ComObjPtr<Medium> &aMedium, bool aLockWrite)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mIsLocked)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return VBOX_E_INVALID_OBJECT_STATE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumLocks.push_back(MediumLock(aMedium, aLockWrite));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockList::Prepend(const ComObjPtr<Medium> &aMedium, bool aLockWrite)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mIsLocked)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return VBOX_E_INVALID_OBJECT_STATE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumLocks.push_front(MediumLock(aMedium, aLockWrite));
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockList::Update(const ComObjPtr<Medium> &aMedium, bool aLockWrite)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (MediumLockList::Base::iterator it = mMediumLocks.begin();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it != mMediumLocks.end();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it++)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (it->GetMedium() == aMedium)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return it->UpdateLock(aLockWrite);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return VBOX_E_INVALID_OBJECT_STATE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockList::RemoveByIterator(Base::iterator &aIt)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = aIt->Unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu aIt = mMediumLocks.erase(aIt);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockList::Clear()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = Unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumLocks.clear();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLockList::Base::iterator MediumLockList::GetBegin()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return mMediumLocks.begin();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLockList::Base::iterator MediumLockList::GetEnd()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return mMediumLocks.end();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockList::Lock()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mIsLocked)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (MediumLockList::Base::iterator it = mMediumLocks.begin();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it != mMediumLocks.end();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it++)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = it->Lock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (FAILED(rc))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (MediumLockList::Base::iterator it2 = mMediumLocks.begin();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it2 != it;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it2++)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc2 = it2->Unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu AssertComRC(rc2);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (SUCCEEDED(rc))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked = true;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockList::Unlock()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (!mIsLocked)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (MediumLockList::Base::iterator it = mMediumLocks.begin();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it != mMediumLocks.end();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it++)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc2 = it->Unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (SUCCEEDED(rc) && FAILED(rc2))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = rc2;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked = false;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLockListMap::MediumLockListMap()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked = false;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuMediumLockListMap::~MediumLockListMap()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu Clear();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu // rest is done by the map object's destructor
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry Liubool MediumLockListMap::IsEmpty()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return mMediumLocks.empty();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockListMap::Insert(const ComObjPtr<MediumAttachment> &aMediumAttachment,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu MediumLockList *aMediumLockList)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mIsLocked)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return VBOX_E_INVALID_OBJECT_STATE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumLocks[aMediumAttachment] = aMediumLockList;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockListMap::ReplaceKey(const ComObjPtr<MediumAttachment> &aMediumAttachmentOld,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu const ComObjPtr<MediumAttachment> &aMediumAttachmentNew)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu MediumLockListMap::Base::iterator it = mMediumLocks.find(aMediumAttachmentOld);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (it == mMediumLocks.end())
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return VBOX_E_INVALID_OBJECT_STATE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu MediumLockList *pMediumLockList = it->second;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumLocks.erase(it);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumLocks[aMediumAttachmentNew] = pMediumLockList;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockListMap::Remove(const ComObjPtr<MediumAttachment> &aMediumAttachment)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu MediumLockListMap::Base::iterator it = mMediumLocks.find(aMediumAttachment);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (it == mMediumLocks.end())
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return VBOX_E_INVALID_OBJECT_STATE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumLocks.erase(it);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockListMap::Clear()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = Unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (MediumLockListMap::Base::iterator it = mMediumLocks.begin();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it != mMediumLocks.end();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu )
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu MediumLockList *pMediumLockList = it->second;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu // need an incremented iterator as otherwise erasing invalidates it
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mMediumLocks.erase(it++);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu delete pMediumLockList;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockListMap::Get(const ComObjPtr<MediumAttachment> &aMediumAttachment,
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu MediumLockList * &aMediumLockList)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu MediumLockListMap::Base::iterator it = mMediumLocks.find(aMediumAttachment);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (it == mMediumLocks.end())
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu aMediumLockList = NULL;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return VBOX_E_INVALID_OBJECT_STATE;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu aMediumLockList = it->second;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockListMap::Lock()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (mIsLocked)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (MediumLockListMap::Base::const_iterator it = mMediumLocks.begin();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it != mMediumLocks.end();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it++)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = it->second->Lock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (FAILED(rc))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (MediumLockListMap::Base::const_iterator it2 = mMediumLocks.begin();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it2 != it;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it2++)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc2 = it2->second->Unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu AssertComRC(rc2);
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu break;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (SUCCEEDED(rc))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked = true;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu
a31148363f598def767ac48c5d82e1572e44b935Gerry LiuHRESULT MediumLockListMap::Unlock()
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu{
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (!mIsLocked)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc = S_OK;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu for (MediumLockListMap::Base::const_iterator it = mMediumLocks.begin();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it != mMediumLocks.end();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu it++)
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu {
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu MediumLockList *pMediumLockList = it->second;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu HRESULT rc2 = pMediumLockList->Unlock();
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu if (SUCCEEDED(rc) && FAILED(rc2))
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu rc = rc2;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu }
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu mIsLocked = false;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu return rc;
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu}
a31148363f598def767ac48c5d82e1572e44b935Gerry Liu