vfs: check userland buffers before reading them.
[haiku.git] / src / system / kernel / TeamThreadTables.h
blob5816e934e11f50eccc29579bab33d48f67ce393a
1 /*
2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef KERNEL_TEAM_THREAD_TABLES_H
6 #define KERNEL_TEAM_THREAD_TABLES_H
9 #include <thread_types.h>
12 namespace BKernel {
15 template<typename Element>
16 struct TeamThreadTable {
17 public:
18 typedef typename Element::id_type id_type;
19 typedef typename Element::iterator_type IteratorEntry;
21 struct Iterator {
22 Iterator()
24 fNext(NULL)
28 Iterator(IteratorEntry* nextEntry)
30 _SetNext(nextEntry);
33 bool HasNext() const
35 return fNext != NULL;
38 Element* Next()
40 Element* result = fNext;
41 if (result != NULL)
42 _SetNext(result->GetDoublyLinkedListLink()->next);
44 return result;
47 private:
48 void _SetNext(IteratorEntry* entry)
50 while (entry != NULL) {
51 if (entry->id >= 0) {
52 fNext = static_cast<Element*>(entry);
53 return;
56 entry = entry->GetDoublyLinkedListLink()->next;
59 fNext = NULL;
62 private:
63 Element* fNext;
66 public:
67 TeamThreadTable()
69 fNextSerialNumber(1)
73 status_t Init(size_t initialSize)
75 return fTable.Init(initialSize);
78 void Insert(Element* element)
80 element->serial_number = fNextSerialNumber++;
81 fTable.InsertUnchecked(element);
82 fList.Add(element);
85 void Remove(Element* element)
87 fTable.RemoveUnchecked(element);
88 fList.Remove(element);
91 Element* Lookup(id_type id, bool visibleOnly = true) const
93 Element* element = fTable.Lookup(id);
94 return element != NULL && (!visibleOnly || element->visible)
95 ? element : NULL;
98 /*! Gets an iterator.
99 The iterator iterates through all, including invisible, entries!
101 Iterator GetIterator()
103 return Iterator(fList.Head());
106 void InsertIteratorEntry(IteratorEntry* entry)
108 // add to front
109 entry->id = -1;
110 entry->visible = false;
111 fList.Add(entry, false);
114 void RemoveIteratorEntry(IteratorEntry* entry)
116 fList.Remove(entry);
119 Element* NextElement(IteratorEntry* entry, bool visibleOnly = true)
121 if (entry == fList.Tail())
122 return NULL;
124 IteratorEntry* nextEntry = entry;
126 while (true) {
127 nextEntry = nextEntry->GetDoublyLinkedListLink()->next;
128 if (nextEntry == NULL) {
129 // end of list -- requeue entry at the end and return NULL
130 fList.Remove(entry);
131 fList.Add(entry);
132 return NULL;
135 if (nextEntry->id >= 0 && (!visibleOnly || nextEntry->visible)) {
136 // found an element -- requeue entry after element
137 Element* element = static_cast<Element*>(nextEntry);
138 fList.Remove(entry);
139 fList.InsertAfter(nextEntry, entry);
140 return element;
145 private:
146 struct HashDefinition {
147 typedef id_type KeyType;
148 typedef Element ValueType;
150 size_t HashKey(id_type key) const
152 return key;
155 size_t Hash(Element* value) const
157 return HashKey(value->id);
160 bool Compare(id_type key, Element* value) const
162 return value->id == key;
165 Element*& GetLink(Element* value) const
167 return value->hash_next;
171 typedef BOpenHashTable<HashDefinition> ElementTable;
172 typedef DoublyLinkedList<IteratorEntry> List;
174 private:
175 ElementTable fTable;
176 List fList;
177 int64 fNextSerialNumber;
181 } // namespace BKernel
184 #endif // KERNEL_TEAM_THREAD_TABLES_H