vfs: check userland buffers before reading them.
[haiku.git] / src / kits / app / LooperList.cpp
blobd468c2b2a499e2dd614b53f27e8a1ac4152c8504
1 /*
2 * Copyright 2001-2015, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Erik Jaesler (erik@cgsoftware.com)
7 */
10 //! Maintains a global list of all loopers in a given team.
13 #include "LooperList.h"
15 #include <Autolock.h>
16 #include <Looper.h>
18 #include <algorithm>
19 #include <string.h>
22 using std::vector;
24 namespace BPrivate {
26 BLooperList gLooperList;
29 BLooperList::BLooperList()
31 fLock("BLooperList lock")
36 bool
37 BLooperList::Lock()
39 return fLock.Lock();
43 void
44 BLooperList::Unlock()
46 fLock.Unlock();
50 bool
51 BLooperList::IsLocked()
53 return fLock.IsLocked();
57 void
58 BLooperList::AddLooper(BLooper* looper)
60 BAutolock locker(fLock);
61 AssertLocked();
62 if (!IsLooperValid(looper)) {
63 LooperDataIterator i
64 = find_if(fData.begin(), fData.end(), EmptySlotPred);
65 if (i == fData.end()) {
66 fData.push_back(LooperData(looper));
67 looper->Lock();
68 } else {
69 i->looper = looper;
70 looper->Lock();
76 bool
77 BLooperList::IsLooperValid(const BLooper* looper)
79 BAutolock locker(fLock);
80 AssertLocked();
82 return find_if(fData.begin(), fData.end(),
83 FindLooperPred(looper)) != fData.end();
87 bool
88 BLooperList::RemoveLooper(BLooper* looper)
90 BAutolock locker(fLock);
91 AssertLocked();
93 LooperDataIterator i = find_if(fData.begin(), fData.end(),
94 FindLooperPred(looper));
95 if (i != fData.end()) {
96 i->looper = NULL;
97 return true;
100 return false;
104 void
105 BLooperList::GetLooperList(BList* list)
107 BAutolock locker(fLock);
108 AssertLocked();
110 for (uint32 i = 0; i < fData.size(); ++i) {
111 if (fData[i].looper)
112 list->AddItem(fData[i].looper);
117 int32
118 BLooperList::CountLoopers()
120 BAutolock locker(fLock);
121 AssertLocked();
122 return (int32)fData.size();
126 BLooper*
127 BLooperList::LooperAt(int32 index)
129 BAutolock locker(fLock);
130 AssertLocked();
132 BLooper* looper = NULL;
133 if (index < (int32)fData.size())
134 looper = fData[(uint32)index].looper;
136 return looper;
140 BLooper*
141 BLooperList::LooperForThread(thread_id thread)
143 BAutolock locker(fLock);
144 AssertLocked();
146 BLooper* looper = NULL;
147 LooperDataIterator i
148 = find_if(fData.begin(), fData.end(), FindThreadPred(thread));
149 if (i != fData.end())
150 looper = i->looper;
152 return looper;
156 BLooper*
157 BLooperList::LooperForName(const char* name)
159 BAutolock locker(fLock);
160 AssertLocked();
162 BLooper* looper = NULL;
163 LooperDataIterator i
164 = find_if(fData.begin(), fData.end(), FindNamePred(name));
165 if (i != fData.end())
166 looper = i->looper;
168 return looper;
172 BLooper*
173 BLooperList::LooperForPort(port_id port)
175 BAutolock locker(fLock);
176 AssertLocked();
178 BLooper* looper = NULL;
179 LooperDataIterator i
180 = find_if(fData.begin(), fData.end(), FindPortPred(port));
181 if (i != fData.end())
182 looper = i->looper;
184 return looper;
188 void
189 BLooperList::InitAfterFork()
191 // We need to reinitialize the locker to get a new semaphore
192 new (&fLock) BLocker("BLooperList lock");
193 fData.clear();
197 bool
198 BLooperList::EmptySlotPred(LooperData& data)
200 return data.looper == NULL;
204 void
205 BLooperList::AssertLocked()
207 if (!IsLocked())
208 debugger("looperlist is not locked; proceed at great risk!");
212 // #pragma mark - BLooperList::LooperData
215 BLooperList::LooperData::LooperData()
217 looper(NULL)
222 BLooperList::LooperData::LooperData(BLooper* looper)
224 looper(looper)
229 BLooperList::LooperData::LooperData(const LooperData& other)
231 *this = other;
235 BLooperList::LooperData&
236 BLooperList::LooperData::operator=(const LooperData& other)
238 if (this != &other)
239 looper = other.looper;
241 return *this;
245 bool
246 BLooperList::FindLooperPred::operator()(BLooperList::LooperData& data)
248 return data.looper && looper == data.looper;
252 bool
253 BLooperList::FindThreadPred::operator()(LooperData& data)
255 return data.looper && thread == data.looper->Thread();
259 bool
260 BLooperList::FindNamePred::operator()(LooperData& data)
262 return data.looper && !strcmp(name, data.looper->Name());
266 bool
267 BLooperList::FindPortPred::operator()(LooperData& data)
269 return data.looper && port == _get_looper_port_(data.looper);
272 } // namespace BPrivate