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 }