VirtualBox

source: vbox/trunk/src/VBox/Main/include/objectslist.h@ 53390

Last change on this file since 53390 was 52317, checked in by vboxsync, 10 years ago

Main/include/objectslist.h: comment

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.4 KB
Line 
1/** @file
2 *
3 * List of COM objects
4 */
5
6/*
7 * Copyright (C) 2009-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ____H_OBJECTSLIST
19#define ____H_OBJECTSLIST
20
21#include <list>
22#include <VBox/com/ptr.h>
23
24/**
25 * Implements a "flat" objects list with a lock. Since each such list
26 * has its own lock it is not a good idea to implement trees with this.
27 *
28 * ObjectList<T> is designed to behave as if it were a std::list of
29 * COM pointers of class T; in other words,
30 * ObjectList<Medium> behaves like std::list< ComObjPtr<Medium> > but
31 * it's less typing. Iterators, front(), size(), begin() and end()
32 * are implemented.
33 *
34 * In addition it automatically includes an RWLockHandle which can be
35 * accessed with getLockHandle().
36 *
37 * If you need the raw std::list for some reason you can access it with
38 * getList().
39 *
40 * The destructor automatically calls uninit() on every contained
41 * COM object. If this is not desired, clear the member list before
42 * deleting the list object.
43 */
44template<typename T>
45class ObjectsList
46{
47public:
48 typedef ComObjPtr<T> MyType;
49 typedef std::list<MyType> MyList;
50
51 typedef typename MyList::iterator iterator;
52 typedef typename MyList::const_iterator const_iterator;
53 // typename is necessary to disambiguate "::iterator" in templates; see
54 // the "this might hurt your head" part in
55 // http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18
56
57 ObjectsList(RWLockHandle &lockHandle)
58 : m_lock(lockHandle)
59 { }
60
61 ~ObjectsList()
62 {
63 uninitAll();
64 }
65
66private:
67 // prohibit copying and assignment
68 ObjectsList(const ObjectsList &d);
69 ObjectsList& operator=(const ObjectsList &d);
70
71public:
72
73 /**
74 * Returns the lock handle which protects this list, for use with
75 * AutoReadLock or AutoWriteLock.
76 */
77 RWLockHandle& getLockHandle()
78 {
79 return m_lock;
80 }
81
82 /**
83 * Calls m_ll.push_back(p) with locking.
84 * @param p
85 */
86 void addChild(MyType p)
87 {
88 AutoWriteLock al(m_lock COMMA_LOCKVAL_SRC_POS);
89 m_ll.push_back(p);
90 }
91
92 /**
93 * Calls m_ll.remove(p) with locking. Does NOT call uninit()
94 * on the contained object.
95 * @param p
96 */
97 void removeChild(MyType p)
98 {
99 AutoWriteLock al(m_lock COMMA_LOCKVAL_SRC_POS);
100 m_ll.remove(p);
101 }
102
103 /**
104 * Appends all objects from another list to the member list.
105 * Locks the other list for reading but does not lock "this"
106 * (because it might be on the caller's stack and needs no
107 * locking).
108 * @param ll
109 */
110 void appendOtherList(ObjectsList<T> &ll)
111 {
112 AutoReadLock alr(ll.getLockHandle() COMMA_LOCKVAL_SRC_POS);
113 for (const_iterator it = ll.begin();
114 it != ll.end();
115 ++it)
116 {
117 m_ll.push_back(*it);
118 }
119 }
120
121 /**
122 * Calls uninit() on every COM object on the list and then
123 * clears the list, with locking.
124 */
125 void uninitAll()
126 {
127 /* The implementation differs from the high level description, because
128 * it isn't safe to hold any locks when invoking uninit() methods. It
129 * leads to incorrect lock order (first lock, then the Caller related
130 * event semaphore) and thus deadlocks. Dropping the lock is vital,
131 * and means we can't rely on iterators while not holding the lock. */
132 AutoWriteLock al(m_lock COMMA_LOCKVAL_SRC_POS);
133 while (!m_ll.empty())
134 {
135 /* Need a copy of the element, have to delete the entry before
136 * dropping the lock, otherwise someone else might mess with the
137 * list in the mean time, leading to erratic behavior. */
138 MyType q = m_ll.front();
139 m_ll.pop_front();
140 al.release();
141 q->uninit();
142 al.acquire();
143 }
144 }
145
146 /**
147 * Returns the no. of objects on the list (std::list compatibility)
148 * with locking.
149 */
150 size_t size()
151 {
152 AutoReadLock al(m_lock COMMA_LOCKVAL_SRC_POS);
153 return m_ll.size();
154 }
155
156 /**
157 * Returns a raw pointer to the member list of objects.
158 * Does not lock!
159 * @return
160 */
161 MyList& getList()
162 {
163 return m_ll;
164 }
165
166 /**
167 * Returns the first object on the list (std::list compatibility)
168 * with locking.
169 */
170 MyType front()
171 {
172 AutoReadLock al(m_lock COMMA_LOCKVAL_SRC_POS);
173 return m_ll.front();
174 }
175
176 /**
177 * Returns the begin iterator from the list (std::list compatibility).
178 * Does not lock!
179 * @return
180 */
181 iterator begin()
182 {
183 return m_ll.begin();
184 }
185
186 /**
187 * Returns the end iterator from the list (std::list compatibility).
188 * Does not lock!
189 */
190 iterator end()
191 {
192 return m_ll.end();
193 }
194
195 void insert(iterator it, MyType &p)
196 {
197 m_ll.insert(it, p);
198 }
199
200 void erase(iterator it)
201 {
202 m_ll.erase(it);
203 }
204
205private:
206 MyList m_ll;
207 RWLockHandle &m_lock;
208};
209
210#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette