15edcfe96SAxel Dörfler/*
29bc4bd38SAxel Dörfler * Copyright 2001-2015, Haiku.
35edcfe96SAxel Dörfler * Distributed under the terms of the MIT License.
45edcfe96SAxel Dörfler *
55edcfe96SAxel Dörfler * Authors:
65edcfe96SAxel Dörfler *		Erik Jaesler (erik@cgsoftware.com)
75edcfe96SAxel Dörfler */
8df226cd7Sejakowatz
9d2e28b60SAxel Dörfler
105edcfe96SAxel Dörfler//! Maintains a global list of all loopers in a given team.
11df226cd7Sejakowatz
12df226cd7Sejakowatz
13df226cd7Sejakowatz#include "LooperList.h"
14df226cd7Sejakowatz
155edcfe96SAxel Dörfler#include <Autolock.h>
165edcfe96SAxel Dörfler#include <Looper.h>
175edcfe96SAxel Dörfler
185edcfe96SAxel Dörfler#include <algorithm>
1918cd67c7SMichael Lotz#include <string.h>
205edcfe96SAxel Dörfler
21df226cd7Sejakowatz
22df226cd7Sejakowatzusing std::vector;
23df226cd7Sejakowatz
24df226cd7Sejakowatznamespace BPrivate {
25df226cd7Sejakowatz
26df226cd7SejakowatzBLooperList gLooperList;
27df226cd7Sejakowatz
28df226cd7Sejakowatz
29df226cd7SejakowatzBLooperList::BLooperList()
305edcfe96SAxel Dörfler	:
31aa33d0a9SAxel Dörfler	fLock("BLooperList lock")
32df226cd7Sejakowatz{
33df226cd7Sejakowatz}
345edcfe96SAxel Dörfler
355edcfe96SAxel Dörfler
365edcfe96SAxel Dörflerbool
375edcfe96SAxel DörflerBLooperList::Lock()
38df226cd7Sejakowatz{
39df226cd7Sejakowatz	return fLock.Lock();
40df226cd7Sejakowatz}
415edcfe96SAxel Dörfler
425edcfe96SAxel Dörfler
435edcfe96SAxel Dörflervoid
445edcfe96SAxel DörflerBLooperList::Unlock()
45df226cd7Sejakowatz{
46df226cd7Sejakowatz	fLock.Unlock();
47df226cd7Sejakowatz}
485edcfe96SAxel Dörfler
495edcfe96SAxel Dörfler
505edcfe96SAxel Dörflerbool
515edcfe96SAxel DörflerBLooperList::IsLocked()
52df226cd7Sejakowatz{
53df226cd7Sejakowatz	return fLock.IsLocked();
54df226cd7Sejakowatz}
555edcfe96SAxel Dörfler
565edcfe96SAxel Dörfler
575edcfe96SAxel Dörflervoid
585edcfe96SAxel DörflerBLooperList::AddLooper(BLooper* looper)
59df226cd7Sejakowatz{
60d2e28b60SAxel Dörfler	BAutolock locker(fLock);
61df226cd7Sejakowatz	AssertLocked();
625edcfe96SAxel Dörfler	if (!IsLooperValid(looper)) {
63d2e28b60SAxel Dörfler		LooperDataIterator i
64d2e28b60SAxel Dörfler			= find_if(fData.begin(), fData.end(), EmptySlotPred);
655edcfe96SAxel Dörfler		if (i == fData.end()) {
66aa33d0a9SAxel Dörfler			fData.push_back(LooperData(looper));
67df226cd7Sejakowatz			looper->Lock();
685edcfe96SAxel Dörfler		} else {
69df226cd7Sejakowatz			i->looper = looper;
70df226cd7Sejakowatz			looper->Lock();
71df226cd7Sejakowatz		}
72df226cd7Sejakowatz	}
73df226cd7Sejakowatz}
745edcfe96SAxel Dörfler
755edcfe96SAxel Dörfler
765edcfe96SAxel Dörflerbool
775edcfe96SAxel DörflerBLooperList::IsLooperValid(const BLooper* looper)
78df226cd7Sejakowatz{
79d2e28b60SAxel Dörfler	BAutolock locker(fLock);
80df226cd7Sejakowatz	AssertLocked();
81df226cd7Sejakowatz
825edcfe96SAxel Dörfler	return find_if(fData.begin(), fData.end(),
835edcfe96SAxel Dörfler		FindLooperPred(looper)) != fData.end();
84df226cd7Sejakowatz}
855edcfe96SAxel Dörfler
865edcfe96SAxel Dörfler
875edcfe96SAxel Dörflerbool
885edcfe96SAxel DörflerBLooperList::RemoveLooper(BLooper* looper)
89df226cd7Sejakowatz{
90d2e28b60SAxel Dörfler	BAutolock locker(fLock);
91df226cd7Sejakowatz	AssertLocked();
92df226cd7Sejakowatz
935edcfe96SAxel Dörfler	LooperDataIterator i = find_if(fData.begin(), fData.end(),
945edcfe96SAxel Dörfler		FindLooperPred(looper));
955edcfe96SAxel Dörfler	if (i != fData.end()) {
96df226cd7Sejakowatz		i->looper = NULL;
97df226cd7Sejakowatz		return true;
98df226cd7Sejakowatz	}
99df226cd7Sejakowatz
100df226cd7Sejakowatz	return false;
101df226cd7Sejakowatz}
1025edcfe96SAxel Dörfler
1035edcfe96SAxel Dörfler
1045edcfe96SAxel Dörflervoid
1055edcfe96SAxel DörflerBLooperList::GetLooperList(BList* list)
106df226cd7Sejakowatz{
107d2e28b60SAxel Dörfler	BAutolock locker(fLock);
108df226cd7Sejakowatz	AssertLocked();
1095edcfe96SAxel Dörfler
1105edcfe96SAxel Dörfler	for (uint32 i = 0; i < fData.size(); ++i) {
111f79cd266SAdi Oanca		if (fData[i].looper)
112f79cd266SAdi Oanca			list->AddItem(fData[i].looper);
113df226cd7Sejakowatz	}
114df226cd7Sejakowatz}
1155edcfe96SAxel Dörfler
1165edcfe96SAxel Dörfler
1175edcfe96SAxel Dörflerint32
1185edcfe96SAxel DörflerBLooperList::CountLoopers()
119ebbcbbcaSejakowatz{
120d2e28b60SAxel Dörfler	BAutolock locker(fLock);
121ebbcbbcaSejakowatz	AssertLocked();
122ebbcbbcaSejakowatz	return (int32)fData.size();
123ebbcbbcaSejakowatz}
1245edcfe96SAxel Dörfler
1255edcfe96SAxel Dörfler
1265edcfe96SAxel DörflerBLooper*
1275edcfe96SAxel DörflerBLooperList::LooperAt(int32 index)
128ebbcbbcaSejakowatz{
129d2e28b60SAxel Dörfler	BAutolock locker(fLock);
130ebbcbbcaSejakowatz	AssertLocked();
131ebbcbbcaSejakowatz
1325edcfe96SAxel Dörfler	BLooper* looper = NULL;
133ebbcbbcaSejakowatz	if (index < (int32)fData.size())
1345edcfe96SAxel Dörfler		looper = fData[(uint32)index].looper;
135ebbcbbcaSejakowatz
1365edcfe96SAxel Dörfler	return looper;
137ebbcbbcaSejakowatz}
1385edcfe96SAxel Dörfler
1395edcfe96SAxel Dörfler
1405edcfe96SAxel DörflerBLooper*
1415edcfe96SAxel DörflerBLooperList::LooperForThread(thread_id thread)
142df226cd7Sejakowatz{
143d2e28b60SAxel Dörfler	BAutolock locker(fLock);
144df226cd7Sejakowatz	AssertLocked();
145d2e28b60SAxel Dörfler
146df226cd7Sejakowatz	BLooper* looper = NULL;
147d2e28b60SAxel Dörfler	LooperDataIterator i
148d2e28b60SAxel Dörfler		= find_if(fData.begin(), fData.end(), FindThreadPred(thread));
149df226cd7Sejakowatz	if (i != fData.end())
150df226cd7Sejakowatz		looper = i->looper;
151df226cd7Sejakowatz
152df226cd7Sejakowatz	return looper;
153df226cd7Sejakowatz}
1545edcfe96SAxel Dörfler
1555edcfe96SAxel Dörfler
1565edcfe96SAxel DörflerBLooper*
1575edcfe96SAxel DörflerBLooperList::LooperForName(const char* name)
158df226cd7Sejakowatz{
159d2e28b60SAxel Dörfler	BAutolock locker(fLock);
160df226cd7Sejakowatz	AssertLocked();
161d2e28b60SAxel Dörfler
162df226cd7Sejakowatz	BLooper* looper = NULL;
163d2e28b60SAxel Dörfler	LooperDataIterator i
164d2e28b60SAxel Dörfler		= find_if(fData.begin(), fData.end(), FindNamePred(name));
165df226cd7Sejakowatz	if (i != fData.end())
166df226cd7Sejakowatz		looper = i->looper;
167df226cd7Sejakowatz
168df226cd7Sejakowatz	return looper;
169df226cd7Sejakowatz}
1705edcfe96SAxel Dörfler
1715edcfe96SAxel Dörfler
1725edcfe96SAxel DörflerBLooper*
1735edcfe96SAxel DörflerBLooperList::LooperForPort(port_id port)
174df226cd7Sejakowatz{
175d2e28b60SAxel Dörfler	BAutolock locker(fLock);
176df226cd7Sejakowatz	AssertLocked();
177d2e28b60SAxel Dörfler
178df226cd7Sejakowatz	BLooper* looper = NULL;
179d2e28b60SAxel Dörfler	LooperDataIterator i
180d2e28b60SAxel Dörfler		= find_if(fData.begin(), fData.end(), FindPortPred(port));
181df226cd7Sejakowatz	if (i != fData.end())
182df226cd7Sejakowatz		looper = i->looper;
183df226cd7Sejakowatz
184df226cd7Sejakowatz	return looper;
185df226cd7Sejakowatz}
1865edcfe96SAxel Dörfler
1875edcfe96SAxel Dörfler
188ef889769SAxel Dörflervoid
189ef889769SAxel DörflerBLooperList::InitAfterFork()
190ef889769SAxel Dörfler{
191ef889769SAxel Dörfler	// We need to reinitialize the locker to get a new semaphore
192ef889769SAxel Dörfler	new (&fLock) BLocker("BLooperList lock");
1939bc4bd38SAxel Dörfler	fData.clear();
194ef889769SAxel Dörfler}
195ef889769SAxel Dörfler
196ef889769SAxel Dörfler
1975edcfe96SAxel Dörflerbool
198d2e28b60SAxel DörflerBLooperList::EmptySlotPred(LooperData& data)
199df226cd7Sejakowatz{
200d2e28b60SAxel Dörfler	return data.looper == NULL;
201df226cd7Sejakowatz}
2025edcfe96SAxel Dörfler
2035edcfe96SAxel Dörfler
2045edcfe96SAxel Dörflervoid
2055edcfe96SAxel DörflerBLooperList::AssertLocked()
206df226cd7Sejakowatz{
207df226cd7Sejakowatz	if (!IsLocked())
208df226cd7Sejakowatz		debugger("looperlist is not locked; proceed at great risk!");
209df226cd7Sejakowatz}
210df226cd7Sejakowatz
211df226cd7Sejakowatz
2125edcfe96SAxel Dörfler//	#pragma mark - BLooperList::LooperData
2135edcfe96SAxel Dörfler
2145edcfe96SAxel Dörfler
215df226cd7SejakowatzBLooperList::LooperData::LooperData()
216d2e28b60SAxel Dörfler	:
217d2e28b60SAxel Dörfler	looper(NULL)
218df226cd7Sejakowatz{
219df226cd7Sejakowatz}
2205edcfe96SAxel Dörfler
2215edcfe96SAxel Dörfler
222aa33d0a9SAxel DörflerBLooperList::LooperData::LooperData(BLooper* looper)
223d2e28b60SAxel Dörfler	:
224d2e28b60SAxel Dörfler	looper(looper)
225df226cd7Sejakowatz{
226df226cd7Sejakowatz}
2275edcfe96SAxel Dörfler
2285edcfe96SAxel Dörfler
2295edcfe96SAxel DörflerBLooperList::LooperData::LooperData(const LooperData& other)
230df226cd7Sejakowatz{
2315edcfe96SAxel Dörfler	*this = other;
232df226cd7Sejakowatz}
2335edcfe96SAxel Dörfler
2345edcfe96SAxel Dörfler
235df226cd7SejakowatzBLooperList::LooperData&
2365edcfe96SAxel DörflerBLooperList::LooperData::operator=(const LooperData& other)
237df226cd7Sejakowatz{
238aa33d0a9SAxel Dörfler	if (this != &other)
2395edcfe96SAxel Dörfler		looper = other.looper;
240df226cd7Sejakowatz
241df226cd7Sejakowatz	return *this;
242df226cd7Sejakowatz}
243df226cd7Sejakowatz
244df226cd7Sejakowatz
2455edcfe96SAxel Dörflerbool
246d2e28b60SAxel DörflerBLooperList::FindLooperPred::operator()(BLooperList::LooperData& data)
247df226cd7Sejakowatz{
248d2e28b60SAxel Dörfler	return data.looper && looper == data.looper;
249df226cd7Sejakowatz}
2505edcfe96SAxel Dörfler
2515edcfe96SAxel Dörfler
2525edcfe96SAxel Dörflerbool
253d2e28b60SAxel DörflerBLooperList::FindThreadPred::operator()(LooperData& data)
254df226cd7Sejakowatz{
255d2e28b60SAxel Dörfler	return data.looper && thread == data.looper->Thread();
256df226cd7Sejakowatz}
2575edcfe96SAxel Dörfler
2585edcfe96SAxel Dörfler
2595edcfe96SAxel Dörflerbool
260d2e28b60SAxel DörflerBLooperList::FindNamePred::operator()(LooperData& data)
261df226cd7Sejakowatz{
262d2e28b60SAxel Dörfler	return data.looper && !strcmp(name, data.looper->Name());
263df226cd7Sejakowatz}
2645edcfe96SAxel Dörfler
2655edcfe96SAxel Dörfler
2665edcfe96SAxel Dörflerbool
267d2e28b60SAxel DörflerBLooperList::FindPortPred::operator()(LooperData& data)
268df226cd7Sejakowatz{
269d2e28b60SAxel Dörfler	return data.looper && port == _get_looper_port_(data.looper);
270df226cd7Sejakowatz}
271df226cd7Sejakowatz
272df226cd7Sejakowatz}	// namespace BPrivate
273df226cd7Sejakowatz
274