/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2020 Edouard Griffiths, F4EXB // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation as version 3 of the License, or // // (at your option) any later version. // // // // This program 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 General Public License V3 for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// #include #include "messagepipesgcworker.h" #include "messagepipes.h" MessagePipes::MessagePipes() : m_typeCount(0), m_c2fMutex(QMutex::Recursive) { m_gcWorker = new MessagePipesGCWorker(); m_gcWorker->setC2FRegistrations(&m_c2fMutex, &m_c2fQueues, &m_c2fFEatures); m_gcWorker->moveToThread(&m_gcThread); startGC(); } MessagePipes::~MessagePipes() { if (m_gcWorker->isRunning()) { stopGC(); } QMap>::iterator mit = m_c2fQueues.begin(); for (; mit != m_c2fQueues.end(); ++mit) { QList::iterator lit = mit->begin(); for (; lit != mit->end(); ++lit) { delete *lit; } } } MessageQueue *MessagePipes::registerChannelToFeature(const ChannelAPI *source, Feature *feature, const QString& type) { int typeId; QMutexLocker mlock(&m_c2fMutex); if (m_typeIds.contains(type)) { typeId = m_typeIds.value(type); } else { typeId++; m_typeIds.insert(type, typeId); } const MessagePipesCommon::ChannelRegistrationKey regKey = MessagePipesCommon::ChannelRegistrationKey{source, typeId}; MessageQueue *messageQueue; if (m_c2fFEatures[regKey].contains(feature)) { int i = m_c2fFEatures[regKey].indexOf(feature); messageQueue = m_c2fQueues[regKey][i]; } else { messageQueue = new MessageQueue(); m_c2fQueues[regKey].append(messageQueue); m_c2fFEatures[regKey].append(feature); } return messageQueue; } void MessagePipes::unregisterChannelToFeature(const ChannelAPI *source, Feature *feature, const QString& type) { if (m_typeIds.contains(type)) { int typeId = m_typeIds.value(type); const MessagePipesCommon::ChannelRegistrationKey regKey = MessagePipesCommon::ChannelRegistrationKey{source, typeId}; if (m_c2fFEatures.contains(regKey) && m_c2fFEatures[regKey].contains(feature)) { QMutexLocker mlock(&m_c2fMutex); int i = m_c2fFEatures[regKey].indexOf(feature); m_c2fFEatures[regKey].removeAt(i); MessageQueue *messageQueue = m_c2fQueues[regKey][i]; delete messageQueue; m_c2fQueues[regKey].removeAt(i); } } } QList* MessagePipes::getMessageQueues(const ChannelAPI *source, const QString& type) { if (!m_typeIds.contains(type)) { return nullptr; } QMutexLocker mlock(&m_c2fMutex); const MessagePipesCommon::ChannelRegistrationKey regKey = MessagePipesCommon::ChannelRegistrationKey{source, m_typeIds.value(type)}; if (m_c2fQueues.contains(regKey)) { return &m_c2fQueues[regKey]; } else { return nullptr; } } void MessagePipes::startGC() { qDebug("MessagePipes::startGC"); m_gcWorker->startWork(); m_gcThread.start(); } void MessagePipes::stopGC() { qDebug("MessagePipes::stopGC"); m_gcWorker->stopWork(); m_gcThread.quit(); m_gcThread.wait(); }