mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-09-27 15:26:33 -04:00
Added MessagePipes garbage collector. Updated versions and changelogs
This commit is contained in:
parent
ba642e8fab
commit
38a06c4f69
@ -1,3 +1,12 @@
|
|||||||
|
sdrangel (6.3.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Implemented garbage collector for message pipes. Applies to VORLocalizer.
|
||||||
|
* FreeDV: removed useless set callback functions. Use mutex appropriately. Issue #728
|
||||||
|
* ATV demod: initialize m_tvScreenBuffer when setting m_registeredTVScreen. Issue #728
|
||||||
|
* TVScreenAnalog: removed usage of std::shared_ptr. Issue #728
|
||||||
|
|
||||||
|
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sat, 12 Dec 2020 14:45:22 +0100
|
||||||
|
|
||||||
sdrangel (6.3.0-1) unstable; urgency=medium
|
sdrangel (6.3.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Single channel VOR demodulator plugin. Issue #729
|
* Single channel VOR demodulator plugin. Issue #729
|
||||||
|
@ -16,7 +16,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
# configure version
|
# configure version
|
||||||
set(sdrangel_VERSION_MAJOR "6")
|
set(sdrangel_VERSION_MAJOR "6")
|
||||||
set(sdrangel_VERSION_MINOR "3")
|
set(sdrangel_VERSION_MINOR "3")
|
||||||
set(sdrangel_VERSION_PATCH "0")
|
set(sdrangel_VERSION_PATCH "1")
|
||||||
set(sdrangel_VERSION_SUFFIX "")
|
set(sdrangel_VERSION_SUFFIX "")
|
||||||
|
|
||||||
# SDRAngel cmake options
|
# SDRAngel cmake options
|
||||||
|
9
debian/changelog
vendored
9
debian/changelog
vendored
@ -1,3 +1,12 @@
|
|||||||
|
sdrangel (6.3.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Implemented garbage collector for message pipes. Applies to VORLocalizer.
|
||||||
|
* FreeDV: removed useless set callback functions. Use mutex appropriately. Issue #728
|
||||||
|
* ATV demod: initialize m_tvScreenBuffer when setting m_registeredTVScreen. Issue #728
|
||||||
|
* TVScreenAnalog: removed usage of std::shared_ptr. Issue #728
|
||||||
|
|
||||||
|
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sat, 12 Dec 2020 14:45:22 +0100
|
||||||
|
|
||||||
sdrangel (6.3.0-1) unstable; urgency=medium
|
sdrangel (6.3.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Single channel VOR demodulator plugin. Issue #729
|
* Single channel VOR demodulator plugin. Issue #729
|
||||||
|
@ -30,7 +30,7 @@ const PluginDescriptor ATVDemodPlugin::m_ptrPluginDescriptor =
|
|||||||
{
|
{
|
||||||
ATVDemod::m_channelId,
|
ATVDemod::m_channelId,
|
||||||
QString("ATV Demodulator"),
|
QString("ATV Demodulator"),
|
||||||
QString("4.19.0"),
|
QString("6.3.1"),
|
||||||
QString("(c) F4HKW for F4EXB / SDRAngel"),
|
QString("(c) F4HKW for F4EXB / SDRAngel"),
|
||||||
QString("https://github.com/f4exb/sdrangel"),
|
QString("https://github.com/f4exb/sdrangel"),
|
||||||
true,
|
true,
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
const PluginDescriptor FreeDVPlugin::m_pluginDescriptor = {
|
const PluginDescriptor FreeDVPlugin::m_pluginDescriptor = {
|
||||||
FreeDVDemod::m_channelId,
|
FreeDVDemod::m_channelId,
|
||||||
QStringLiteral("FreeDV Demodulator"),
|
QStringLiteral("FreeDV Demodulator"),
|
||||||
QStringLiteral("4.19.0"),
|
QStringLiteral("6.3.1"),
|
||||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||||
true,
|
true,
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
const PluginDescriptor FreeDVModPlugin::m_pluginDescriptor = {
|
const PluginDescriptor FreeDVModPlugin::m_pluginDescriptor = {
|
||||||
FreeDVMod::m_channelId,
|
FreeDVMod::m_channelId,
|
||||||
QStringLiteral("FreeDV Modulator"),
|
QStringLiteral("FreeDV Modulator"),
|
||||||
QStringLiteral("6.1.0"),
|
QStringLiteral("6.3.1"),
|
||||||
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
|
||||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||||
true,
|
true,
|
||||||
|
@ -218,7 +218,7 @@ bool VORLocalizer::handleMessage(const Message& cmd)
|
|||||||
}
|
}
|
||||||
else if (VORLocalizerReport::MsgReportServiceddVORs::match(cmd))
|
else if (VORLocalizerReport::MsgReportServiceddVORs::match(cmd))
|
||||||
{
|
{
|
||||||
qDebug() << "VORLocalizer::handleMessage: MsgReportServiceddVORs:";
|
qDebug() << "VORLocalizer::handleMessage: MsgReportServiceddVORs";
|
||||||
VORLocalizerReport::MsgReportServiceddVORs& report = (VORLocalizerReport::MsgReportServiceddVORs&) cmd;
|
VORLocalizerReport::MsgReportServiceddVORs& report = (VORLocalizerReport::MsgReportServiceddVORs&) cmd;
|
||||||
std::vector<int>& vorNavIds = report.getNavIds();
|
std::vector<int>& vorNavIds = report.getNavIds();
|
||||||
m_vorSinglePlans = report.getSinglePlans();
|
m_vorSinglePlans = report.getSinglePlans();
|
||||||
@ -239,6 +239,18 @@ bool VORLocalizer::handleMessage(const Message& cmd)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (MessagePipesCommon::MsgReportChannelDeleted::match(cmd))
|
||||||
|
{
|
||||||
|
qDebug() << "VORLocalizer::handleMessage: MsgReportChannelDeleted";
|
||||||
|
MessagePipesCommon::MsgReportChannelDeleted& report = (MessagePipesCommon::MsgReportChannelDeleted&) cmd;
|
||||||
|
const MessagePipesCommon::ChannelRegistrationKey& channelKey = report.getChannelRegistrationKey();
|
||||||
|
const ChannelAPI *channel = channelKey.m_channel;
|
||||||
|
m_availableChannels.remove(const_cast<ChannelAPI*>(channel));
|
||||||
|
updateChannels();
|
||||||
|
MainCore::instance()->getMessagePipes().unregisterChannelToFeature(channel, this, "report");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -366,6 +378,7 @@ void VORLocalizer::updateChannels()
|
|||||||
{
|
{
|
||||||
VORLocalizerReport::MsgReportChannels *msgToGUI = VORLocalizerReport::MsgReportChannels::create();
|
VORLocalizerReport::MsgReportChannels *msgToGUI = VORLocalizerReport::MsgReportChannels::create();
|
||||||
std::vector<VORLocalizerReport::MsgReportChannels::Channel>& msgChannels = msgToGUI->getChannels();
|
std::vector<VORLocalizerReport::MsgReportChannels::Channel>& msgChannels = msgToGUI->getChannels();
|
||||||
|
// TODO: check https://github.com/microsoft/vscode-cpptools/issues/6222
|
||||||
QHash<ChannelAPI*, VORLocalizerSettings::AvailableChannel>::iterator it = m_availableChannels.begin();
|
QHash<ChannelAPI*, VORLocalizerSettings::AvailableChannel>::iterator it = m_availableChannels.begin();
|
||||||
|
|
||||||
for (; it != m_availableChannels.end(); ++it)
|
for (; it != m_availableChannels.end(); ++it)
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
const PluginDescriptor VORLocalizerPlugin::m_pluginDescriptor = {
|
const PluginDescriptor VORLocalizerPlugin::m_pluginDescriptor = {
|
||||||
VORLocalizer::m_featureId,
|
VORLocalizer::m_featureId,
|
||||||
QStringLiteral("VOR Localizer"),
|
QStringLiteral("VOR Localizer"),
|
||||||
QStringLiteral("6.3.0"),
|
QStringLiteral("6.3.1"),
|
||||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||||
true,
|
true,
|
||||||
|
@ -161,6 +161,8 @@ set(sdrbase_SOURCES
|
|||||||
limerfe/limerfeusbcalib.cpp
|
limerfe/limerfeusbcalib.cpp
|
||||||
|
|
||||||
pipes/messagepipes.cpp
|
pipes/messagepipes.cpp
|
||||||
|
pipes/messagepipescommon.cpp
|
||||||
|
pipes/messagepipesgcworker.cpp
|
||||||
|
|
||||||
settings/featuresetpreset.cpp
|
settings/featuresetpreset.cpp
|
||||||
settings/preferences.cpp
|
settings/preferences.cpp
|
||||||
@ -335,6 +337,8 @@ set(sdrbase_HEADERS
|
|||||||
limerfe/limerfeusbcalib.h
|
limerfe/limerfeusbcalib.h
|
||||||
|
|
||||||
pipes/messagepipes.h
|
pipes/messagepipes.h
|
||||||
|
pipes/messagepipescommon.h
|
||||||
|
pipes/messagepipesgcworker.h
|
||||||
|
|
||||||
plugin/plugininterface.h
|
plugin/plugininterface.h
|
||||||
plugin/pluginapi.h
|
plugin/pluginapi.h
|
||||||
|
@ -449,8 +449,8 @@ public:
|
|||||||
void setLoggingOptions();
|
void setLoggingOptions();
|
||||||
ChannelAPI *getChannel(unsigned int deviceSetIndex, int channelIndex);
|
ChannelAPI *getChannel(unsigned int deviceSetIndex, int channelIndex);
|
||||||
Feature *getFeature(unsigned int featureSetIndex, int featureIndex);
|
Feature *getFeature(unsigned int featureSetIndex, int featureIndex);
|
||||||
bool existsChannel(ChannelAPI *channel) const { return m_channelsMap.contains(channel); }
|
bool existsChannel(const ChannelAPI *channel) const { return m_channelsMap.contains(const_cast<ChannelAPI*>(channel)); }
|
||||||
bool existsFeature(Feature *feature) const { return m_featuresMap.contains(feature); }
|
bool existsFeature(const Feature *feature) const { return m_featuresMap.contains(const_cast<Feature*>(feature)); }
|
||||||
// slave mode
|
// slave mode
|
||||||
void appendFeatureSet();
|
void appendFeatureSet();
|
||||||
void removeFeatureSet(unsigned int index);
|
void removeFeatureSet(unsigned int index);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2015 Edouard Griffiths, F4EXB //
|
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
|
||||||
// //
|
// //
|
||||||
// This program is free software; you can redistribute it and/or modify //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -17,26 +17,28 @@
|
|||||||
|
|
||||||
#include <QGlobalStatic>
|
#include <QGlobalStatic>
|
||||||
|
|
||||||
|
#include "messagepipesgcworker.h"
|
||||||
#include "messagepipes.h"
|
#include "messagepipes.h"
|
||||||
|
|
||||||
bool MessagePipes::ChannelRegistrationKey::operator<(const ChannelRegistrationKey& other) const
|
|
||||||
{
|
|
||||||
if (m_channel != other.m_channel) {
|
|
||||||
return m_channel < other.m_channel;
|
|
||||||
} else {
|
|
||||||
return m_typeId < other.m_typeId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MessagePipes::MessagePipes() :
|
MessagePipes::MessagePipes() :
|
||||||
m_typeCount(0)
|
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()
|
MessagePipes::~MessagePipes()
|
||||||
{
|
{
|
||||||
QMap<ChannelRegistrationKey, QList<MessageQueue*>>::iterator mit = m_messageRegistrations.begin();
|
if (m_gcWorker->isRunning()) {
|
||||||
|
stopGC();
|
||||||
|
}
|
||||||
|
|
||||||
for (; mit != m_messageRegistrations.end(); ++mit)
|
QMap<MessagePipesCommon::ChannelRegistrationKey, QList<MessageQueue*>>::iterator mit = m_c2fQueues.begin();
|
||||||
|
|
||||||
|
for (; mit != m_c2fQueues.end(); ++mit)
|
||||||
{
|
{
|
||||||
QList<MessageQueue*>::iterator lit = mit->begin();
|
QList<MessageQueue*>::iterator lit = mit->begin();
|
||||||
|
|
||||||
@ -46,9 +48,10 @@ MessagePipes::~MessagePipes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueue *MessagePipes::registerChannelToFeature(const ChannelAPI *source, const Feature *feature, const QString& type)
|
MessageQueue *MessagePipes::registerChannelToFeature(const ChannelAPI *source, Feature *feature, const QString& type)
|
||||||
{
|
{
|
||||||
int typeId;
|
int typeId;
|
||||||
|
QMutexLocker mlock(&m_c2fMutex);
|
||||||
|
|
||||||
if (m_typeIds.contains(type))
|
if (m_typeIds.contains(type))
|
||||||
{
|
{
|
||||||
@ -60,32 +63,71 @@ MessageQueue *MessagePipes::registerChannelToFeature(const ChannelAPI *source, c
|
|||||||
m_typeIds.insert(type, typeId);
|
m_typeIds.insert(type, typeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChannelRegistrationKey regKey = ChannelRegistrationKey{source, typeId};
|
const MessagePipesCommon::ChannelRegistrationKey regKey = MessagePipesCommon::ChannelRegistrationKey{source, typeId};
|
||||||
|
MessageQueue *messageQueue;
|
||||||
|
|
||||||
if (m_messageRegistrations.contains(regKey))
|
if (m_c2fFEatures[regKey].contains(feature))
|
||||||
{
|
{
|
||||||
m_messageRegistrations.insert(regKey, QList<MessageQueue*>());
|
int i = m_c2fFEatures[regKey].indexOf(feature);
|
||||||
m_featureRegistrations.insert(regKey, QList<const Feature*>());
|
messageQueue = m_c2fQueues[regKey][i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
messageQueue = new MessageQueue();
|
||||||
|
m_c2fQueues[regKey].append(messageQueue);
|
||||||
|
m_c2fFEatures[regKey].append(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueue *messageQueue = new MessageQueue();
|
|
||||||
m_messageRegistrations[regKey].append(messageQueue);
|
|
||||||
m_featureRegistrations[regKey].append(feature);
|
|
||||||
|
|
||||||
return messageQueue;
|
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<MessageQueue*>* MessagePipes::getMessageQueues(const ChannelAPI *source, const QString& type)
|
QList<MessageQueue*>* MessagePipes::getMessageQueues(const ChannelAPI *source, const QString& type)
|
||||||
{
|
{
|
||||||
if (!m_typeIds.contains(type)) {
|
if (!m_typeIds.contains(type)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChannelRegistrationKey regKey = ChannelRegistrationKey{source, m_typeIds.value(type)};
|
QMutexLocker mlock(&m_c2fMutex);
|
||||||
|
const MessagePipesCommon::ChannelRegistrationKey regKey = MessagePipesCommon::ChannelRegistrationKey{source, m_typeIds.value(type)};
|
||||||
|
|
||||||
if (m_messageRegistrations.contains(regKey)) {
|
if (m_c2fQueues.contains(regKey)) {
|
||||||
return &m_messageRegistrations[regKey];
|
return &m_c2fQueues[regKey];
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
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();
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
// Copyright (C) 2015 Edouard Griffiths, F4EXB //
|
// Copyright (C) 2020 Edouard Griffiths, F4EXB //
|
||||||
// //
|
// //
|
||||||
// This program is free software; you can redistribute it and/or modify //
|
// 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 //
|
// it under the terms of the GNU General Public License as published by //
|
||||||
@ -21,38 +21,42 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
#include "util/messagequeue.h"
|
#include "util/messagequeue.h"
|
||||||
|
|
||||||
|
#include "messagepipescommon.h"
|
||||||
|
|
||||||
class ChannelAPI;
|
class ChannelAPI;
|
||||||
class Feature;
|
class Feature;
|
||||||
|
class MessagePipesGCWorker;
|
||||||
|
|
||||||
class SDRBASE_API MessagePipes : public QObject
|
class SDRBASE_API MessagePipes : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
struct ChannelRegistrationKey
|
|
||||||
{
|
|
||||||
const ChannelAPI *m_channel;
|
|
||||||
int m_typeId;
|
|
||||||
|
|
||||||
bool operator<(const ChannelRegistrationKey& other) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
MessagePipes();
|
MessagePipes();
|
||||||
MessagePipes(const MessagePipes&) = delete;
|
MessagePipes(const MessagePipes&) = delete;
|
||||||
MessagePipes& operator=(const MessagePipes&) = delete;
|
MessagePipes& operator=(const MessagePipes&) = delete;
|
||||||
~MessagePipes();
|
~MessagePipes();
|
||||||
|
|
||||||
MessageQueue *registerChannelToFeature(const ChannelAPI *source, const Feature *feature, const QString& type);
|
MessageQueue *registerChannelToFeature(const ChannelAPI *source, Feature *feature, const QString& type);
|
||||||
|
void unregisterChannelToFeature(const ChannelAPI *source, Feature *feature, const QString& type);
|
||||||
QList<MessageQueue*>* getMessageQueues(const ChannelAPI *source, const QString& type);
|
QList<MessageQueue*>* getMessageQueues(const ChannelAPI *source, const QString& type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<QString, int> m_typeIds;
|
QHash<QString, int> m_typeIds;
|
||||||
int m_typeCount;
|
int m_typeCount;
|
||||||
QMap<ChannelRegistrationKey, QList<MessageQueue*>> m_messageRegistrations;
|
QMap<MessagePipesCommon::ChannelRegistrationKey, QList<MessageQueue*>> m_c2fQueues;
|
||||||
QMap<ChannelRegistrationKey, QList<const Feature*>> m_featureRegistrations;
|
QMap<MessagePipesCommon::ChannelRegistrationKey, QList<Feature*>> m_c2fFEatures;
|
||||||
|
QMutex m_c2fMutex;
|
||||||
|
QThread m_gcThread; //!< Garbage collector thread
|
||||||
|
MessagePipesGCWorker *m_gcWorker; //!< Garbage collector
|
||||||
|
|
||||||
|
void startGC(); //!< Start garbage collector
|
||||||
|
void stopGC(); //!< Stop garbage collector
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SDRBASE_PIPES_MESSAGEPIPES_H_
|
#endif // SDRBASE_PIPES_MESSAGEPIPES_H_
|
||||||
|
29
sdrbase/pipes/messagepipescommon.cpp
Normal file
29
sdrbase/pipes/messagepipescommon.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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 <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "messagepipescommon.h"
|
||||||
|
|
||||||
|
MESSAGE_CLASS_DEFINITION(MessagePipesCommon::MsgReportChannelDeleted, Message)
|
||||||
|
|
||||||
|
bool MessagePipesCommon::ChannelRegistrationKey::operator<(const ChannelRegistrationKey& other) const
|
||||||
|
{
|
||||||
|
if (m_channel != other.m_channel) {
|
||||||
|
return m_channel < other.m_channel;
|
||||||
|
} else {
|
||||||
|
return m_typeId < other.m_typeId;
|
||||||
|
}
|
||||||
|
}
|
70
sdrbase/pipes/messagepipescommon.h
Normal file
70
sdrbase/pipes/messagepipescommon.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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 <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRBASE_PIPES_MESSAGEPIPESCOMON_H_
|
||||||
|
#define SDRBASE_PIPES_MESSAGEPIPESCOMON_H_
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
#include "export.h"
|
||||||
|
#include "util/message.h"
|
||||||
|
|
||||||
|
class ChannelAPI;
|
||||||
|
class Feature;
|
||||||
|
class MessageQueue;
|
||||||
|
|
||||||
|
class SDRBASE_API MessagePipesCommon
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct ChannelRegistrationKey
|
||||||
|
{
|
||||||
|
const ChannelAPI *m_channel;
|
||||||
|
int m_typeId;
|
||||||
|
|
||||||
|
ChannelRegistrationKey() = default;
|
||||||
|
ChannelRegistrationKey(const ChannelRegistrationKey&) = default;
|
||||||
|
ChannelRegistrationKey& operator=(const ChannelRegistrationKey&) = default;
|
||||||
|
bool operator<(const ChannelRegistrationKey& other) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Send this message to stakeholders when the garbage collector finds that a channel was deleted */
|
||||||
|
class MsgReportChannelDeleted : public Message {
|
||||||
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
|
||||||
|
public:
|
||||||
|
const MessageQueue *getMessageQueue() const { return m_messageQueue; }
|
||||||
|
const ChannelRegistrationKey& getChannelRegistrationKey() const { return m_channelRegistrationKey; }
|
||||||
|
|
||||||
|
static MsgReportChannelDeleted* create(const MessageQueue *messageQueue, const ChannelRegistrationKey& channelRegistrationKey) {
|
||||||
|
return new MsgReportChannelDeleted(messageQueue, channelRegistrationKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const MessageQueue *m_messageQueue;
|
||||||
|
ChannelRegistrationKey m_channelRegistrationKey;
|
||||||
|
|
||||||
|
MsgReportChannelDeleted(const MessageQueue *messageQueue, const ChannelRegistrationKey& channelRegistrationKey) :
|
||||||
|
Message(),
|
||||||
|
m_messageQueue(messageQueue),
|
||||||
|
m_channelRegistrationKey(channelRegistrationKey)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SDRBASE_PIPES_MESSAGEPIPESCOMON_H_
|
115
sdrbase/pipes/messagepipesgcworker.cpp
Normal file
115
sdrbase/pipes/messagepipesgcworker.cpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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 <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "feature/feature.h"
|
||||||
|
#include "maincore.h"
|
||||||
|
#include "messagepipescommon.h"
|
||||||
|
#include "messagepipesgcworker.h"
|
||||||
|
|
||||||
|
MessagePipesGCWorker::MessagePipesGCWorker() :
|
||||||
|
m_running(false),
|
||||||
|
m_c2fMutex(nullptr),
|
||||||
|
m_c2fQueues(nullptr),
|
||||||
|
m_c2fFeatures(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
MessagePipesGCWorker::~MessagePipesGCWorker()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void MessagePipesGCWorker::startWork()
|
||||||
|
{
|
||||||
|
connect(&m_gcTimer, SIGNAL(timeout()), this, SLOT(processGC()));
|
||||||
|
m_gcTimer.start(10000); // collect garbage every 10s
|
||||||
|
m_running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagePipesGCWorker::stopWork()
|
||||||
|
{
|
||||||
|
m_running = false;
|
||||||
|
m_gcTimer.stop();
|
||||||
|
disconnect(&m_gcTimer, SIGNAL(timeout()), this, SLOT(processGC()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagePipesGCWorker::processGC()
|
||||||
|
{
|
||||||
|
// qDebug("MessagePipesGCWorker::processGC");
|
||||||
|
if (m_c2fMutex)
|
||||||
|
{
|
||||||
|
QMutexLocker mlock(m_c2fMutex);
|
||||||
|
QMap<MessagePipesCommon::ChannelRegistrationKey, QList<Feature*>>::iterator fIt = m_c2fFeatures->begin();
|
||||||
|
|
||||||
|
// check deleted channels and features
|
||||||
|
for (;fIt != m_c2fFeatures->end(); ++fIt)
|
||||||
|
{
|
||||||
|
MessagePipesCommon::ChannelRegistrationKey channelKey = fIt.key();
|
||||||
|
const ChannelAPI *channel = channelKey.m_channel;
|
||||||
|
|
||||||
|
if (MainCore::instance()->existsChannel(channel)) // look for deleted features
|
||||||
|
{
|
||||||
|
QList<Feature*>& features = fIt.value();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < features.size())
|
||||||
|
{
|
||||||
|
if (MainCore::instance()->existsFeature(features[i])) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
features.removeAt(i);
|
||||||
|
m_c2fQueues->operator[](channelKey).removeAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // channel was destroyed
|
||||||
|
{
|
||||||
|
QList<Feature*>& features = fIt.value();
|
||||||
|
|
||||||
|
for (int i = 0; i < features.size(); i++)
|
||||||
|
{
|
||||||
|
MessagePipesCommon::MsgReportChannelDeleted *msg = MessagePipesCommon::MsgReportChannelDeleted::create(
|
||||||
|
m_c2fQueues->operator[](channelKey)[i], channelKey);
|
||||||
|
features[i]->getInputMessageQueue()->push(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove keys with empty features
|
||||||
|
fIt = m_c2fFeatures->begin();
|
||||||
|
|
||||||
|
while (fIt != m_c2fFeatures->end())
|
||||||
|
{
|
||||||
|
if (fIt.value().size() == 0) {
|
||||||
|
fIt = m_c2fFeatures->erase(fIt);
|
||||||
|
} else {
|
||||||
|
++fIt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove keys with empty message queues
|
||||||
|
QMap<MessagePipesCommon::ChannelRegistrationKey, QList<MessageQueue*>>::iterator qIt = m_c2fQueues->begin();
|
||||||
|
|
||||||
|
while (qIt != m_c2fQueues->end())
|
||||||
|
{
|
||||||
|
if (qIt.value().size() == 0) {
|
||||||
|
qIt = m_c2fQueues->erase(qIt);
|
||||||
|
} else {
|
||||||
|
++qIt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
63
sdrbase/pipes/messagepipesgcworker.h
Normal file
63
sdrbase/pipes/messagepipesgcworker.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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 <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRBASE_PIPES_MESSAGEPIPESGCWORKER_H_
|
||||||
|
#define SDRBASE_PIPES_MESSAGEPIPESGCWORKER_H_
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "export.h"
|
||||||
|
|
||||||
|
#include "messagepipescommon.h"
|
||||||
|
|
||||||
|
class QMutex;
|
||||||
|
|
||||||
|
class SDRBASE_API MessagePipesGCWorker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MessagePipesGCWorker();
|
||||||
|
~MessagePipesGCWorker();
|
||||||
|
|
||||||
|
void setC2FRegistrations(
|
||||||
|
QMutex *c2fMutex,
|
||||||
|
QMap<MessagePipesCommon::ChannelRegistrationKey, QList<MessageQueue*>> *c2fQueues,
|
||||||
|
QMap<MessagePipesCommon::ChannelRegistrationKey, QList<Feature*>> *c2fFeatures
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_c2fMutex = c2fMutex;
|
||||||
|
m_c2fQueues = c2fQueues;
|
||||||
|
m_c2fFeatures = c2fFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
void startWork();
|
||||||
|
void stopWork();
|
||||||
|
bool isRunning() const { return m_running; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_running;
|
||||||
|
QMutex *m_c2fMutex;
|
||||||
|
QMap<MessagePipesCommon::ChannelRegistrationKey, QList<MessageQueue*>> *m_c2fQueues ;
|
||||||
|
QMap<MessagePipesCommon::ChannelRegistrationKey, QList<Feature*>> *m_c2fFeatures;
|
||||||
|
QTimer m_gcTimer;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void processGC(); //!< Collect garbage
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user