summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/include/MediumLock.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/include/MediumLock.h')
-rw-r--r--src/VBox/Main/include/MediumLock.h351
1 files changed, 351 insertions, 0 deletions
diff --git a/src/VBox/Main/include/MediumLock.h b/src/VBox/Main/include/MediumLock.h
new file mode 100644
index 00000000..ad02501a
--- /dev/null
+++ b/src/VBox/Main/include/MediumLock.h
@@ -0,0 +1,351 @@
+/* $Id: MediumLock.h $ */
+
+/** @file
+ *
+ * VirtualBox medium object lock collections
+ */
+
+/*
+ * Copyright (C) 2010-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MediumLock_h
+#define MAIN_INCLUDED_MediumLock_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+/* interface definitions */
+#include "VBox/com/VirtualBox.h"
+#include "VirtualBoxBase.h"
+#include "AutoCaller.h"
+
+#include <iprt/types.h>
+
+#include <list>
+#include <map>
+
+class Medium;
+class MediumAttachment;
+
+/**
+ * Single entry for medium lock lists. Has a medium object reference,
+ * information about what kind of lock should be taken, and if it is
+ * locked right now.
+ */
+class MediumLock
+{
+public:
+ /**
+ * Default medium lock constructor.
+ */
+ MediumLock();
+
+ /**
+ * Default medium lock destructor.
+ */
+ ~MediumLock();
+
+ /**
+ * Create a new medium lock description
+ *
+ * @param aMedium Reference to medium object
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ MediumLock(const ComObjPtr<Medium> &aMedium, bool aLockWrite);
+
+ /**
+ * Copy constructor. Needed because we contain an AutoCaller
+ * instance which is deliberately not copyable. The copy is not
+ * marked as locked, so be careful.
+ *
+ * @param aMediumLock Reference to source object.
+ */
+ MediumLock(const MediumLock &aMediumLock);
+
+ /**
+ * Update a medium lock description.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ HRESULT UpdateLock(bool aLockWrite);
+
+ /**
+ * Get medium object reference.
+ */
+ const ComObjPtr<Medium> &GetMedium() const;
+
+ /**
+ * Get medium object lock request type.
+ */
+ bool GetLockRequest() const;
+
+ /**
+ * Check if this medium object has been locked by this MediumLock.
+ */
+ bool IsLocked() const;
+
+ /**
+ * Acquire a medium lock.
+ *
+ * @return COM status code
+ * @param aIgnoreLockedMedia If set ignore all media which is already
+ * locked in an incompatible way.
+ */
+ HRESULT Lock(bool aIgnoreLockedMedia = false);
+
+ /**
+ * Release a medium lock.
+ *
+ * @return COM status code
+ */
+ HRESULT Unlock();
+
+private:
+ ComObjPtr<Medium> mMedium;
+ ComPtr<IToken> mToken;
+ AutoCaller mMediumCaller;
+ bool mLockWrite;
+ bool mIsLocked;
+ /** Flag whether the medium was skipped when taking the locks.
+ * Only existing and accessible media objects need to be locked. */
+ bool mLockSkipped;
+};
+
+
+/**
+ * Medium lock list. Meant for storing the ordered locking information
+ * for a single medium chain.
+ */
+class MediumLockList
+{
+public:
+
+ /* Base list data type. */
+ typedef std::list<MediumLock> Base;
+
+ /**
+ * Default medium lock list constructor.
+ */
+ MediumLockList();
+
+ /**
+ * Default medium lock list destructor.
+ */
+ ~MediumLockList();
+
+ /**
+ * Checks if medium lock declaration list is empty.
+ *
+ * @return true if list is empty.
+ */
+ bool IsEmpty();
+
+ /**
+ * Add a new medium lock declaration to the end of the list.
+ *
+ * @note May be only used in unlocked state.
+ *
+ * @return COM status code
+ * @param aMedium Reference to medium object
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ HRESULT Append(const ComObjPtr<Medium> &aMedium, bool aLockWrite);
+
+ /**
+ * Add a new medium lock declaration to the beginning of the list.
+ *
+ * @note May be only used in unlocked state.
+ *
+ * @return COM status code
+ * @param aMedium Reference to medium object
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ HRESULT Prepend(const ComObjPtr<Medium> &aMedium, bool aLockWrite);
+
+ /**
+ * Update a medium lock declaration.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aMedium Reference to medium object
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ HRESULT Update(const ComObjPtr<Medium> &aMedium, bool aLockWrite);
+
+ /**
+ * Remove a medium lock declaration and return an updated iterator.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aIt Iterator for the element to remove
+ */
+ HRESULT RemoveByIterator(Base::iterator &aIt);
+
+ /**
+ * Clear all medium lock declarations.
+ *
+ * @note Implicitly unlocks all locks.
+ *
+ * @return COM status code
+ */
+ HRESULT Clear();
+
+ /**
+ * Get iterator begin() for base list.
+ */
+ Base::iterator GetBegin();
+
+ /**
+ * Get iterator end() for base list.
+ */
+ Base::iterator GetEnd();
+
+ /**
+ * Acquire all medium locks "atomically", i.e. all or nothing.
+ *
+ * @return COM status code
+ * @param aSkipOverLockedMedia If set ignore all media which is already
+ * locked for reading or writing. For callers
+ * which need to know which medium objects
+ * have been locked by this lock list you
+ * can iterate over the list and check the
+ * MediumLock state.
+ */
+ HRESULT Lock(bool aSkipOverLockedMedia = false);
+
+ /**
+ * Release all medium locks.
+ *
+ * @return COM status code
+ */
+ HRESULT Unlock();
+
+private:
+ Base mMediumLocks;
+ bool mIsLocked;
+};
+
+/**
+ * Medium lock list map. Meant for storing a collection of lock lists.
+ * The usual use case is creating such a map when locking all medium chains
+ * belonging to one VM, however that's not the limit. Be creative.
+ */
+class MediumLockListMap
+{
+public:
+
+ /**
+ * Default medium lock list map constructor.
+ */
+ MediumLockListMap();
+
+ /**
+ * Default medium lock list map destructor.
+ */
+ ~MediumLockListMap();
+
+ /**
+ * Checks if medium lock list map is empty.
+ *
+ * @return true if list is empty.
+ */
+ bool IsEmpty();
+
+ /**
+ * Insert a new medium lock list into the map.
+ *
+ * @note May be only used in unlocked state.
+ *
+ * @return COM status code
+ * @param aMediumAttachment Reference to medium attachment object, the key.
+ * @param aMediumLockList Reference to medium lock list object
+ */
+ HRESULT Insert(const ComObjPtr<MediumAttachment> &aMediumAttachment, MediumLockList *aMediumLockList);
+
+ /**
+ * Replace the medium lock list key by a different one.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aMediumAttachmentOld Reference to medium attachment object.
+ * @param aMediumAttachmentNew Reference to medium attachment object.
+ */
+ HRESULT ReplaceKey(const ComObjPtr<MediumAttachment> &aMediumAttachmentOld, const ComObjPtr<MediumAttachment> &aMediumAttachmentNew);
+
+ /**
+ * Remove a medium lock list from the map. The list will get deleted.
+ *
+ * @note May be only used in unlocked state.
+ *
+ * @return COM status code
+ * @param aMediumAttachment Reference to medium attachment object, the key.
+ */
+ HRESULT Remove(const ComObjPtr<MediumAttachment> &aMediumAttachment);
+
+ /**
+ * Clear all medium lock declarations in this map.
+ *
+ * @note Implicitly unlocks all locks.
+ *
+ * @return COM status code
+ */
+ HRESULT Clear();
+
+ /**
+ * Get the medium lock list identified by the given key.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aMediumAttachment Key for medium attachment object.
+ * @param aMediumLockList Out: medium attachment object reference.
+ */
+ HRESULT Get(const ComObjPtr<MediumAttachment> &aMediumAttachment, MediumLockList * &aMediumLockList);
+
+ /**
+ * Acquire all medium locks "atomically", i.e. all or nothing.
+ *
+ * @return COM status code
+ */
+ HRESULT Lock();
+
+ /**
+ * Release all medium locks.
+ *
+ * @return COM status code
+ */
+ HRESULT Unlock();
+
+private:
+ typedef std::map<ComObjPtr<MediumAttachment>, MediumLockList *> Base;
+ Base mMediumLocks;
+ bool mIsLocked;
+};
+
+#endif /* !MAIN_INCLUDED_MediumLock_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */