File indexing completed on 2024-11-10 04:40:25
0001 /* 0002 SPDX-FileCopyrightText: 2010 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "agentserver.h" 0008 #include "agentthread.h" 0009 #include "akonadiagentserver_debug.h" 0010 0011 #include "private/dbus_p.h" 0012 0013 #include <QCoreApplication> 0014 #include <QDBusConnection> 0015 #include <QPluginLoader> 0016 #include <QTimer> 0017 0018 using namespace Akonadi; 0019 using namespace std::chrono_literals; 0020 AgentServer::AgentServer(QObject *parent) 0021 : QObject(parent) 0022 { 0023 QDBusConnection::sessionBus().registerObject(QStringLiteral(AKONADI_DBUS_AGENTSERVER_PATH), this, QDBusConnection::ExportScriptableSlots); 0024 } 0025 0026 AgentServer::~AgentServer() 0027 { 0028 qCDebug(AKONADIAGENTSERVER_LOG) << Q_FUNC_INFO; 0029 if (!m_quiting) { 0030 quit(); 0031 } 0032 } 0033 0034 void AgentServer::agentInstanceConfigure(const QString &identifier, qlonglong windowId) 0035 { 0036 m_configureQueue.enqueue(ConfigureInfo(identifier, windowId)); 0037 if (!m_processingConfigureRequests) { // Start processing the requests if needed. 0038 QTimer::singleShot(0s, this, &AgentServer::processConfigureRequest); 0039 } 0040 } 0041 0042 bool AgentServer::started(const QString &identifier) const 0043 { 0044 return m_agents.contains(identifier); 0045 } 0046 0047 void AgentServer::startAgent(const QString &identifier, const QString &typeIdentifier, const QString &fileName) 0048 { 0049 qCDebug(AKONADIAGENTSERVER_LOG) << "Starting agent" << identifier << "of type" << typeIdentifier << "(file:" << fileName << ")"; 0050 0051 // First try to load it statically 0052 const QObjectList objList = QPluginLoader::staticInstances(); 0053 for (QObject *plugin : objList) { 0054 if (plugin->objectName() == fileName) { 0055 auto thread = new AgentThread(identifier, plugin, this); 0056 m_agents.insert(identifier, thread); 0057 thread->start(); 0058 return; 0059 } 0060 } 0061 0062 QPluginLoader *loader = m_agentLoader.load(fileName); 0063 if (!loader) { 0064 return; // No plugin found, debug output in AgentLoader. 0065 } 0066 0067 Q_ASSERT(loader->isLoaded()); 0068 0069 auto thread = new AgentThread(identifier, loader->instance(), this); 0070 m_agents.insert(identifier, thread); 0071 thread->start(); 0072 } 0073 0074 void AgentServer::stopAgent(const QString &identifier) 0075 { 0076 AgentThread *thread = m_agents.take(identifier); 0077 if (thread) { 0078 thread->quit(); 0079 thread->wait(); 0080 delete thread; 0081 } 0082 } 0083 0084 void AgentServer::quit() 0085 { 0086 Q_ASSERT(!m_quiting); 0087 m_quiting = true; 0088 0089 QMutableHashIterator<QString, AgentThread *> it(m_agents); 0090 while (it.hasNext()) { 0091 stopAgent(it.next().key()); 0092 } 0093 0094 QCoreApplication::instance()->quit(); 0095 } 0096 0097 void AgentServer::processConfigureRequest() 0098 { 0099 if (m_processingConfigureRequests) { 0100 return; // Protect against reentrancy 0101 } 0102 0103 m_processingConfigureRequests = true; 0104 0105 while (!m_configureQueue.empty()) { 0106 const ConfigureInfo info = m_configureQueue.dequeue(); 0107 // call configure on the agent with id info.first for windowId info.second. 0108 Q_ASSERT(m_agents.contains(info.first)); 0109 AgentThread *thread = m_agents.value(info.first); 0110 thread->configure(info.second); 0111 } 0112 0113 m_processingConfigureRequests = false; 0114 } 0115 0116 #include "moc_agentserver.cpp"