/* * 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 #include #include #include 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