1 /* 2 * Copyright 2001-2005, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Erik Jaesler (erik@cgsoftware.com) 7 */ 8 9 //! Maintains a global list of all loopers in a given team. 10 11 12 #include "LooperList.h" 13 14 #include <Autolock.h> 15 #include <Looper.h> 16 17 #include <algorithm> 18 19 20 using std::vector; 21 22 namespace BPrivate { 23 24 BLooperList gLooperList; 25 26 typedef vector<BLooperList::LooperData>::iterator LooperDataIterator; 27 28 29 BLooperList::BLooperList() 30 : 31 fLock("BLooperList lock"), 32 fLooperID(0) 33 { 34 } 35 36 37 bool 38 BLooperList::Lock() 39 { 40 return fLock.Lock(); 41 } 42 43 44 void 45 BLooperList::Unlock() 46 { 47 fLock.Unlock(); 48 } 49 50 51 bool 52 BLooperList::IsLocked() 53 { 54 return fLock.IsLocked(); 55 } 56 57 58 void 59 BLooperList::AddLooper(BLooper* looper) 60 { 61 BAutolock Listlock(fLock); 62 AssertLocked(); 63 if (!IsLooperValid(looper)) { 64 LooperDataIterator i = find_if(fData.begin(), fData.end(), EmptySlotPred); 65 if (i == fData.end()) { 66 fData.push_back(LooperData(looper, ++fLooperID)); 67 looper->fLooperID = fLooperID; 68 looper->Lock(); 69 } else { 70 i->looper = looper; 71 i->id = ++fLooperID; 72 looper->fLooperID = fLooperID; 73 looper->Lock(); 74 } 75 } 76 } 77 78 79 bool 80 BLooperList::IsLooperValid(const BLooper* looper) 81 { 82 BAutolock Listlock(fLock); 83 AssertLocked(); 84 85 return find_if(fData.begin(), fData.end(), 86 FindLooperPred(looper)) != fData.end(); 87 } 88 89 90 bool 91 BLooperList::RemoveLooper(BLooper* looper) 92 { 93 BAutolock Listlock(fLock); 94 AssertLocked(); 95 96 LooperDataIterator i = find_if(fData.begin(), fData.end(), 97 FindLooperPred(looper)); 98 if (i != fData.end()) { 99 i->looper = NULL; 100 return true; 101 } 102 103 return false; 104 } 105 106 107 void 108 BLooperList::GetLooperList(BList* list) 109 { 110 BAutolock Listlock(fLock); 111 AssertLocked(); 112 113 for (uint32 i = 0; i < fData.size(); ++i) { 114 if (fData[i].looper) 115 list->AddItem(fData[i].looper); 116 } 117 } 118 119 120 int32 121 BLooperList::CountLoopers() 122 { 123 BAutolock Listlock(fLock); 124 AssertLocked(); 125 return (int32)fData.size(); 126 } 127 128 129 BLooper* 130 BLooperList::LooperAt(int32 index) 131 { 132 BAutolock Listlock(fLock); 133 AssertLocked(); 134 135 BLooper* looper = NULL; 136 if (index < (int32)fData.size()) 137 looper = fData[(uint32)index].looper; 138 139 return looper; 140 } 141 142 143 BLooper* 144 BLooperList::LooperForThread(thread_id thread) 145 { 146 BAutolock Listlock(fLock); 147 AssertLocked(); 148 BLooper* looper = NULL; 149 LooperDataIterator i = find_if(fData.begin(), fData.end(), FindThreadPred(thread)); 150 if (i != fData.end()) 151 looper = i->looper; 152 153 return looper; 154 } 155 156 157 BLooper* 158 BLooperList::LooperForName(const char* name) 159 { 160 BAutolock Listlock(fLock); 161 AssertLocked(); 162 BLooper* looper = NULL; 163 LooperDataIterator i = find_if(fData.begin(), fData.end(), FindNamePred(name)); 164 if (i != fData.end()) 165 looper = i->looper; 166 167 return looper; 168 } 169 170 171 BLooper* 172 BLooperList::LooperForPort(port_id port) 173 { 174 BAutolock Listlock(fLock); 175 AssertLocked(); 176 BLooper* looper = NULL; 177 LooperDataIterator i = find_if(fData.begin(), fData.end(), FindPortPred(port)); 178 if (i != fData.end()) 179 looper = i->looper; 180 181 return looper; 182 } 183 184 185 bool 186 BLooperList::EmptySlotPred(LooperData& Data) 187 { 188 return Data.looper == NULL; 189 } 190 191 192 void 193 BLooperList::AssertLocked() 194 { 195 if (!IsLocked()) 196 debugger("looperlist is not locked; proceed at great risk!"); 197 } 198 199 200 // #pragma mark - BLooperList::LooperData 201 202 203 BLooperList::LooperData::LooperData() 204 : looper(NULL), id(0) 205 { 206 } 207 208 209 BLooperList::LooperData::LooperData(BLooper* loop, uint32 i) 210 : looper(loop), id(i) 211 { 212 } 213 214 215 BLooperList::LooperData::LooperData(const LooperData& other) 216 { 217 *this = other; 218 } 219 220 221 BLooperList::LooperData& 222 BLooperList::LooperData::operator=(const LooperData& other) 223 { 224 if (this != &other) { 225 looper = other.looper; 226 id = other.id; 227 } 228 229 return *this; 230 } 231 232 233 bool 234 BLooperList::FindLooperPred::operator()(BLooperList::LooperData& Data) 235 { 236 return Data.looper && looper == Data.looper; 237 } 238 239 240 bool 241 BLooperList::FindThreadPred::operator()(LooperData& Data) 242 { 243 return Data.looper && thread == Data.looper->Thread(); 244 } 245 246 247 bool 248 BLooperList::FindNamePred::operator()(LooperData& Data) 249 { 250 return Data.looper && !strcmp(name, Data.looper->Name()); 251 } 252 253 254 bool 255 BLooperList::FindPortPred::operator()(LooperData& Data) 256 { 257 return Data.looper && port == _get_looper_port_(Data.looper); 258 } 259 260 } // namespace BPrivate 261 262