274 lines
4.0 KiB
C++
274 lines
4.0 KiB
C++
/*
|
|
* Copyright 2001-2015, Haiku.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Erik Jaesler (erik@cgsoftware.com)
|
|
*/
|
|
|
|
|
|
//! Maintains a global list of all loopers in a given team.
|
|
|
|
|
|
#include "LooperList.h"
|
|
|
|
#include <Autolock.h>
|
|
#include <Looper.h>
|
|
|
|
#include <algorithm>
|
|
#include <string.h>
|
|
|
|
|
|
using std::vector;
|
|
|
|
namespace BPrivate {
|
|
|
|
BLooperList gLooperList;
|
|
|
|
|
|
BLooperList::BLooperList()
|
|
:
|
|
fLock("BLooperList lock")
|
|
{
|
|
}
|
|
|
|
|
|
bool
|
|
BLooperList::Lock()
|
|
{
|
|
return fLock.Lock();
|
|
}
|
|
|
|
|
|
void
|
|
BLooperList::Unlock()
|
|
{
|
|
fLock.Unlock();
|
|
}
|
|
|
|
|
|
bool
|
|
BLooperList::IsLocked()
|
|
{
|
|
return fLock.IsLocked();
|
|
}
|
|
|
|
|
|
void
|
|
BLooperList::AddLooper(BLooper* looper)
|
|
{
|
|
BAutolock locker(fLock);
|
|
AssertLocked();
|
|
if (!IsLooperValid(looper)) {
|
|
LooperDataIterator i
|
|
= find_if(fData.begin(), fData.end(), EmptySlotPred);
|
|
if (i == fData.end()) {
|
|
fData.push_back(LooperData(looper));
|
|
looper->Lock();
|
|
} else {
|
|
i->looper = looper;
|
|
looper->Lock();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool
|
|
BLooperList::IsLooperValid(const BLooper* looper)
|
|
{
|
|
BAutolock locker(fLock);
|
|
AssertLocked();
|
|
|
|
return find_if(fData.begin(), fData.end(),
|
|
FindLooperPred(looper)) != fData.end();
|
|
}
|
|
|
|
|
|
bool
|
|
BLooperList::RemoveLooper(BLooper* looper)
|
|
{
|
|
BAutolock locker(fLock);
|
|
AssertLocked();
|
|
|
|
LooperDataIterator i = find_if(fData.begin(), fData.end(),
|
|
FindLooperPred(looper));
|
|
if (i != fData.end()) {
|
|
i->looper = NULL;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
void
|
|
BLooperList::GetLooperList(BList* list)
|
|
{
|
|
BAutolock locker(fLock);
|
|
AssertLocked();
|
|
|
|
for (uint32 i = 0; i < fData.size(); ++i) {
|
|
if (fData[i].looper)
|
|
list->AddItem(fData[i].looper);
|
|
}
|
|
}
|
|
|
|
|
|
int32
|
|
BLooperList::CountLoopers()
|
|
{
|
|
BAutolock locker(fLock);
|
|
AssertLocked();
|
|
return (int32)fData.size();
|
|
}
|
|
|
|
|
|
BLooper*
|
|
BLooperList::LooperAt(int32 index)
|
|
{
|
|
BAutolock locker(fLock);
|
|
AssertLocked();
|
|
|
|
BLooper* looper = NULL;
|
|
if (index < (int32)fData.size())
|
|
looper = fData[(uint32)index].looper;
|
|
|
|
return looper;
|
|
}
|
|
|
|
|
|
BLooper*
|
|
BLooperList::LooperForThread(thread_id thread)
|
|
{
|
|
BAutolock locker(fLock);
|
|
AssertLocked();
|
|
|
|
BLooper* looper = NULL;
|
|
LooperDataIterator i
|
|
= find_if(fData.begin(), fData.end(), FindThreadPred(thread));
|
|
if (i != fData.end())
|
|
looper = i->looper;
|
|
|
|
return looper;
|
|
}
|
|
|
|
|
|
BLooper*
|
|
BLooperList::LooperForName(const char* name)
|
|
{
|
|
BAutolock locker(fLock);
|
|
AssertLocked();
|
|
|
|
BLooper* looper = NULL;
|
|
LooperDataIterator i
|
|
= find_if(fData.begin(), fData.end(), FindNamePred(name));
|
|
if (i != fData.end())
|
|
looper = i->looper;
|
|
|
|
return looper;
|
|
}
|
|
|
|
|
|
BLooper*
|
|
BLooperList::LooperForPort(port_id port)
|
|
{
|
|
BAutolock locker(fLock);
|
|
AssertLocked();
|
|
|
|
BLooper* looper = NULL;
|
|
LooperDataIterator i
|
|
= find_if(fData.begin(), fData.end(), FindPortPred(port));
|
|
if (i != fData.end())
|
|
looper = i->looper;
|
|
|
|
return looper;
|
|
}
|
|
|
|
|
|
void
|
|
BLooperList::InitAfterFork()
|
|
{
|
|
// We need to reinitialize the locker to get a new semaphore
|
|
new (&fLock) BLocker("BLooperList lock");
|
|
fData.clear();
|
|
}
|
|
|
|
|
|
bool
|
|
BLooperList::EmptySlotPred(LooperData& data)
|
|
{
|
|
return data.looper == NULL;
|
|
}
|
|
|
|
|
|
void
|
|
BLooperList::AssertLocked()
|
|
{
|
|
if (!IsLocked())
|
|
debugger("looperlist is not locked; proceed at great risk!");
|
|
}
|
|
|
|
|
|
// #pragma mark - BLooperList::LooperData
|
|
|
|
|
|
BLooperList::LooperData::LooperData()
|
|
:
|
|
looper(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
BLooperList::LooperData::LooperData(BLooper* looper)
|
|
:
|
|
looper(looper)
|
|
{
|
|
}
|
|
|
|
|
|
BLooperList::LooperData::LooperData(const LooperData& other)
|
|
{
|
|
*this = other;
|
|
}
|
|
|
|
|
|
BLooperList::LooperData&
|
|
BLooperList::LooperData::operator=(const LooperData& other)
|
|
{
|
|
if (this != &other)
|
|
looper = other.looper;
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
bool
|
|
BLooperList::FindLooperPred::operator()(BLooperList::LooperData& data)
|
|
{
|
|
return data.looper && looper == data.looper;
|
|
}
|
|
|
|
|
|
bool
|
|
BLooperList::FindThreadPred::operator()(LooperData& data)
|
|
{
|
|
return data.looper && thread == data.looper->Thread();
|
|
}
|
|
|
|
|
|
bool
|
|
BLooperList::FindNamePred::operator()(LooperData& data)
|
|
{
|
|
return data.looper && !strcmp(name, data.looper->Name());
|
|
}
|
|
|
|
|
|
bool
|
|
BLooperList::FindPortPred::operator()(LooperData& data)
|
|
{
|
|
return data.looper && port == _get_looper_port_(data.looper);
|
|
}
|
|
|
|
} // namespace BPrivate
|
|
|