File indexing completed on 2025-01-05 04:37:31
0001 /* 0002 SPDX-FileCopyrightText: 2010 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "resourcemanager.h" 0008 0009 namespace bt 0010 { 0011 Resource::Resource(bt::ResourceManager *rman, const QString &group) 0012 : rman(rman) 0013 , group(group) 0014 { 0015 } 0016 0017 Resource::~Resource() 0018 { 0019 if (rman) 0020 rman->remove(this); 0021 } 0022 0023 void Resource::release() 0024 { 0025 if (rman) { 0026 rman->remove(this); 0027 rman = nullptr; 0028 } 0029 } 0030 0031 ResourceManager::ResourceManager(Uint32 max_active_resources) 0032 : max_active_resources(max_active_resources) 0033 { 0034 } 0035 0036 ResourceManager::~ResourceManager() 0037 { 0038 } 0039 0040 void ResourceManager::add(Resource *r) 0041 { 0042 QMap<QString, Resource::List>::iterator i = pending.find(r->groupName()); 0043 if (i == pending.end()) 0044 i = pending.insert(r->groupName(), Resource::List()); 0045 0046 i.value().append(r); 0047 if (current.isEmpty()) 0048 current = r->groupName(); 0049 update(); 0050 } 0051 0052 bool ResourceManager::acquire(Resource *r) 0053 { 0054 if ((Uint32)active.size() < max_active_resources && pending.isEmpty()) { 0055 add(r); 0056 return true; 0057 } else 0058 return false; 0059 } 0060 0061 void ResourceManager::remove(Resource *r) 0062 { 0063 if (active.remove(r)) { 0064 update(); 0065 } else { 0066 QMap<QString, Resource::List>::iterator i = pending.find(r->groupName()); 0067 if (i != pending.end()) 0068 i.value().removeAll(r); 0069 } 0070 } 0071 0072 void ResourceManager::update() 0073 { 0074 if ((Uint32)active.size() >= max_active_resources) 0075 return; 0076 0077 QMap<QString, Resource::List>::iterator i = pending.find(current); 0078 if (i == pending.end()) 0079 i = pending.begin(); 0080 0081 QMap<QString, Resource::List>::iterator start = i; 0082 Uint32 activated = 0; 0083 while ((Uint32)active.size() < max_active_resources) { 0084 if (!i.value().isEmpty()) { 0085 Resource *r = i.value().takeFirst(); 0086 active.insert(r); 0087 r->acquired(); 0088 activated++; 0089 } 0090 ++i; 0091 if (i == pending.end()) // Loop around 0092 i = pending.begin(); 0093 0094 if (i == start) { // we have completed an antire cycle 0095 if (activated == 0) // Nothing was activated, so exit the loop 0096 break; 0097 else 0098 activated = 0; 0099 } 0100 } 0101 0102 current = i.key(); 0103 } 0104 0105 void ResourceManager::shutdown() 0106 { 0107 max_active_resources = 0; 0108 } 0109 0110 }