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