File indexing completed on 2024-06-23 05:14:14
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 uiserver/sessiondata.cpp 0003 0004 This file is part of Kleopatra, the KDE keymanager 0005 SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include <config-kleopatra.h> 0011 0012 #include "sessiondata.h" 0013 0014 #include "kleopatra_debug.h" 0015 0016 #include <QMutex> 0017 0018 using namespace Kleo; 0019 0020 static const int GARBAGE_COLLECTION_INTERVAL = 60000; // 1min 0021 0022 static QMutex mutex; 0023 0024 SessionData::SessionData() 0025 : mementos() 0026 , ref(0) 0027 , ripe(false) 0028 { 0029 } 0030 0031 // static 0032 std::shared_ptr<SessionDataHandler> SessionDataHandler::instance() 0033 { 0034 mutex.lock(); 0035 static SessionDataHandler handler; 0036 return std::shared_ptr<SessionDataHandler>(&handler, [](SessionDataHandler *) { 0037 mutex.unlock(); 0038 }); 0039 } 0040 0041 SessionDataHandler::SessionDataHandler() 0042 : QObject() 0043 , data() 0044 , timer() 0045 { 0046 timer.setInterval(GARBAGE_COLLECTION_INTERVAL); 0047 timer.setSingleShot(false); 0048 } 0049 0050 void SessionDataHandler::enterSession(unsigned int id) 0051 { 0052 qCDebug(KLEOPATRA_LOG) << id; 0053 const std::shared_ptr<SessionData> sd = sessionDataInternal(id); 0054 Q_ASSERT(sd); 0055 ++sd->ref; 0056 sd->ripe = false; 0057 } 0058 0059 void SessionDataHandler::exitSession(unsigned int id) 0060 { 0061 qCDebug(KLEOPATRA_LOG) << id; 0062 const std::shared_ptr<SessionData> sd = sessionDataInternal(id); 0063 Q_ASSERT(sd); 0064 if (--sd->ref <= 0) { 0065 sd->ref = 0; 0066 sd->ripe = false; 0067 if (!timer.isActive()) { 0068 QMetaObject::invokeMethod(&timer, "start", Qt::QueuedConnection); 0069 } 0070 } 0071 } 0072 0073 std::shared_ptr<SessionData> SessionDataHandler::sessionDataInternal(unsigned int id) const 0074 { 0075 auto it = data.lower_bound(id); 0076 if (it == data.end() || it->first != id) { 0077 const std::shared_ptr<SessionData> sd(new SessionData); 0078 it = data.insert(it, std::make_pair(id, sd)); 0079 } 0080 return it->second; 0081 } 0082 0083 std::shared_ptr<SessionData> SessionDataHandler::sessionData(unsigned int id) const 0084 { 0085 return sessionDataInternal(id); 0086 } 0087 0088 void SessionDataHandler::clear() 0089 { 0090 data.clear(); 0091 } 0092 0093 void SessionDataHandler::slotCollectGarbage() 0094 { 0095 const QMutexLocker locker(&mutex); 0096 unsigned int alive = 0; 0097 auto it = data.begin(), end = data.end(); 0098 while (it != end) 0099 if (it->second->ripe) { 0100 data.erase(it++); 0101 } else if (!it->second->ref) { 0102 it->second->ripe = true; 0103 ++it; 0104 } else { 0105 ++alive; 0106 ++it; 0107 } 0108 if (alive == data.size()) { 0109 QMetaObject::invokeMethod(&timer, "stop", Qt::QueuedConnection); 0110 } 0111 } 0112 0113 #include "moc_sessiondata.cpp"