/* Copyright (c) 2010 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "agentserver.h" #include "agentthread.h" #include "libs/xdgbasedirs_p.h" #include "libs/protocol_p.h" #include "shared/akdebug.h" #include #include #include #include #include using namespace Akonadi; AgentServer::AgentServer( QObject *parent ) : QObject( parent ) , m_processingConfigureRequests( false ) , m_quiting( false ) { QDBusConnection::sessionBus().registerObject( QLatin1String( AKONADI_DBUS_AGENTSERVER_PATH ), this, QDBusConnection::ExportScriptableSlots ); } AgentServer::~AgentServer() { qDebug() << Q_FUNC_INFO; if ( !m_quiting ) { quit(); } } void AgentServer::agentInstanceConfigure( const QString &identifier, qlonglong windowId ) { m_configureQueue.enqueue( ConfigureInfo( identifier, windowId ) ); if ( !m_processingConfigureRequests ) { // Start processing the requests if needed. QTimer::singleShot( 0, this, SLOT(processConfigureRequest()) ); } } bool AgentServer::started( const QString &identifier ) const { return m_agents.contains( identifier ); } void AgentServer::startAgent( const QString &identifier, const QString &typeIdentifier, const QString &fileName ) { akDebug() << Q_FUNC_INFO << identifier << typeIdentifier << fileName; //First try to load it staticly Q_FOREACH ( QObject *plugin, QPluginLoader::staticInstances() ) { if ( plugin->objectName() == fileName ) { AgentThread *thread = new AgentThread( identifier, plugin, this ); m_agents.insert( identifier, thread ); thread->start(); return; } } QPluginLoader *loader = m_agentLoader.load( fileName ); if ( loader == 0 ) { return; // No plugin found, debug output in AgentLoader. } Q_ASSERT( loader->isLoaded() ); AgentThread *thread = new AgentThread( identifier, loader->instance(), this ); m_agents.insert( identifier, thread ); thread->start(); } void AgentServer::stopAgent( const QString &identifier ) { if ( !m_agents.contains( identifier ) ) { return; } AgentThread *thread = m_agents.take( identifier ); thread->quit(); thread->wait(); delete thread; } void AgentServer::quit() { Q_ASSERT( !m_quiting ); m_quiting = true; QMutableHashIterator it( m_agents ); while ( it.hasNext() ) { it.next(); stopAgent( it.key() ); } QCoreApplication::instance()->quit(); } void AgentServer::processConfigureRequest() { if ( m_processingConfigureRequests ) { return; // Protect against reentrancy } m_processingConfigureRequests = true; while ( !m_configureQueue.empty() ) { const ConfigureInfo info = m_configureQueue.dequeue(); // call configure on the agent with id info.first for windowId info.second. Q_ASSERT( m_agents.contains( info.first ) ); AgentThread *thread = m_agents.value( info.first ); thread->configure( info.second ); } m_processingConfigureRequests = false; }