From aca4a535134611ab77802f52e7e037cd7d46fec3 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 18 Aug 2024 13:37:27 +0200 Subject: [PATCH] Fixed threading model for DSPDeviceSinkEngine plus other fixes. Part of #2159 --- sdrbase/dsp/dspdevicesinkengine.cpp | 46 ++++++++--------------------- sdrbase/dsp/dspdevicesinkengine.h | 10 ++----- sdrbase/dsp/dspengine.cpp | 37 ++++++++++++++++++----- sdrgui/mainwindow.cpp | 18 ++--------- sdrsrv/mainserver.cpp | 14 ++------- 5 files changed, 51 insertions(+), 74 deletions(-) diff --git a/sdrbase/dsp/dspdevicesinkengine.cpp b/sdrbase/dsp/dspdevicesinkengine.cpp index 210bd5780..70090a1e3 100644 --- a/sdrbase/dsp/dspdevicesinkengine.cpp +++ b/sdrbase/dsp/dspdevicesinkengine.cpp @@ -28,7 +28,7 @@ #include "dsp/dspcommands.h" DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) : - QThread(parent), + QObject(parent), m_uid(uid), m_state(StNotStarted), m_deviceSampleSink(nullptr), @@ -41,8 +41,6 @@ DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) : { setState(StIdle); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); - - moveToThread(this); } DSPDeviceSinkEngine::~DSPDeviceSinkEngine() @@ -59,29 +57,6 @@ void DSPDeviceSinkEngine::setState(State state) } } -void DSPDeviceSinkEngine::run() -{ - qDebug() << "DSPDeviceSinkEngine::run"; - setState(StIdle); - exec(); -} - -void DSPDeviceSinkEngine::start() -{ - qDebug() << "DSPDeviceSinkEngine::start"; - QThread::start(); -} - -void DSPDeviceSinkEngine::stop() -{ - qDebug() << "DSPDeviceSinkEngine::stop"; - gotoIdle(); - setState(StNotStarted); - QThread::exit(); -// DSPExit cmd; -// m_syncMessenger.sendWait(cmd); -} - bool DSPDeviceSinkEngine::initGeneration() { qDebug() << "DSPDeviceSinkEngine::initGeneration"; @@ -101,7 +76,7 @@ bool DSPDeviceSinkEngine::startGeneration() void DSPDeviceSinkEngine::stopGeneration() { qDebug() << "DSPDeviceSinkEngine::stopGeneration"; - DSPGenerationStop *cmd = new DSPGenerationStop(); + auto *cmd = new DSPGenerationStop(); getInputMessageQueue()->push(cmd); } @@ -122,7 +97,7 @@ void DSPDeviceSinkEngine::setSinkSequence(int sequence) void DSPDeviceSinkEngine::addChannelSource(BasebandSampleSource* source) { qDebug() << "DSPDeviceSinkEngine::addChannelSource: " << source->getSourceName().toStdString().c_str(); - DSPAddBasebandSampleSource *cmd = new DSPAddBasebandSampleSource(source); + auto *cmd = new DSPAddBasebandSampleSource(source); getInputMessageQueue()->push(cmd); } @@ -167,7 +142,10 @@ void DSPDeviceSinkEngine::workSampleFifo() } SampleVector& data = sourceFifo->getData(); - unsigned int iPart1Begin, iPart1End, iPart2Begin, iPart2End; + unsigned int iPart1Begin; + unsigned int iPart1End; + unsigned int iPart2Begin; + unsigned int iPart2End; unsigned int remainder = sourceFifo->remainder(); while ((remainder > 0) && (m_inputMessageQueue.size() == 0)) @@ -208,7 +186,7 @@ void DSPDeviceSinkEngine::workSamples(SampleVector& data, unsigned int iBegin, u else { m_sourceSampleBuffer.allocate(nbSamples); - SampleVector::iterator sBegin = m_sourceSampleBuffer.m_vector.begin(); + auto sBegin = m_sourceSampleBuffer.m_vector.begin(); BasebandSampleSources::const_iterator srcIt = m_basebandSampleSources.begin(); BasebandSampleSource *source = *srcIt; source->pull(begin, nbSamples); @@ -309,7 +287,7 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoInit() m_sampleRate = m_deviceSampleSink->getSampleRate(); qDebug() << "DSPDeviceSinkEngine::gotoInit: " - << " m_deviceDescription: " << m_deviceDescription.toStdString().c_str() + << " m_deviceDescription: " << m_deviceDescription.toStdString().c_str() << " sampleRate: " << m_sampleRate << " centerFrequency: " << m_centerFrequency; @@ -328,7 +306,7 @@ DSPDeviceSinkEngine::State DSPDeviceSinkEngine::gotoInit() // pass data to listeners if (m_deviceSampleSink->getMessageQueueToGUI()) { - DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy for the output queue + auto* rep = new DSPSignalNotification(notif); // make a copy for the output queue m_deviceSampleSink->getMessageQueueToGUI()->push(rep); } @@ -413,7 +391,7 @@ void DSPDeviceSinkEngine::handleSetSink(DeviceSampleSink*) void DSPDeviceSinkEngine::handleData() { if (m_state == StRunning) { - workSampleFifo(); + workSampleFifo(); } } @@ -421,7 +399,7 @@ bool DSPDeviceSinkEngine::handleMessage(const Message& message) { if (DSPSignalNotification::match(message)) { - const DSPSignalNotification& notif = (const DSPSignalNotification&) message; + auto& notif = (const DSPSignalNotification&) message; // update DSP values diff --git a/sdrbase/dsp/dspdevicesinkengine.h b/sdrbase/dsp/dspdevicesinkengine.h index 608028176..db190782d 100644 --- a/sdrbase/dsp/dspdevicesinkengine.h +++ b/sdrbase/dsp/dspdevicesinkengine.h @@ -22,7 +22,7 @@ #ifndef SDRBASE_DSP_DSPDEVICESINKENGINE_H_ #define SDRBASE_DSP_DSPDEVICESINKENGINE_H_ -#include +#include #include #include #include @@ -40,7 +40,7 @@ class DeviceSampleSink; class BasebandSampleSource; class BasebandSampleSink; -class SDRBASE_API DSPDeviceSinkEngine : public QThread { +class SDRBASE_API DSPDeviceSinkEngine : public QObject { Q_OBJECT public: @@ -52,16 +52,13 @@ public: StError //!< engine is in error }; - DSPDeviceSinkEngine(uint32_t uid, QObject* parent = NULL); + DSPDeviceSinkEngine(uint32_t uid, QObject* parent = nullptr); ~DSPDeviceSinkEngine(); uint32_t getUID() const { return m_uid; } MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; } - void start(); //!< This thread start - void stop(); //!< This thread stop - bool initGeneration(); //!< Initialize generation sequence bool startGeneration(); //!< Start generation sequence void stopGeneration(); //!< Stop generation sequence @@ -106,7 +103,6 @@ private: bool m_realElseComplex; unsigned int m_sumIndex; //!< channel index when summing channels - void run(); void workSampleFifo(); //!< transfer samples from baseband sources to sink if in running state void workSamples(SampleVector& data, unsigned int iBegin, unsigned int iEnd); diff --git a/sdrbase/dsp/dspengine.cpp b/sdrbase/dsp/dspengine.cpp index 43e7be763..7e8f72d27 100644 --- a/sdrbase/dsp/dspengine.cpp +++ b/sdrbase/dsp/dspengine.cpp @@ -111,24 +111,45 @@ void DSPEngine::removeLastDeviceSourceEngine() DSPDeviceSinkEngine *DSPEngine::addDeviceSinkEngine() { - m_deviceSinkEngines.push_back(new DSPDeviceSinkEngine(m_deviceSinkEnginesUIDSequence)); + auto *deviceSinkEngine = new DSPDeviceSinkEngine(m_deviceSinkEnginesUIDSequence); + auto *deviceThread = new QThread(); m_deviceSinkEnginesUIDSequence++; - m_deviceEngineReferences.push_back(DeviceEngineReference{1, nullptr, m_deviceSinkEngines.back(), nullptr, nullptr}); - return m_deviceSinkEngines.back(); + m_deviceSinkEngines.push_back(deviceSinkEngine); + m_deviceEngineReferences.push_back(DeviceEngineReference{1, nullptr, m_deviceSinkEngines.back(), nullptr, deviceThread}); + deviceSinkEngine->moveToThread(deviceThread); + + QObject::connect( + deviceThread, + &QThread::finished, + deviceSinkEngine, + &QObject::deleteLater + ); + QObject::connect( + deviceThread, + &QThread::finished, + deviceThread, + &QThread::deleteLater + ); + + deviceThread->start(); + + return deviceSinkEngine; } void DSPEngine::removeLastDeviceSinkEngine() { - if (m_deviceSinkEngines.size() > 0) + if (!m_deviceSinkEngines.empty()) { - DSPDeviceSinkEngine *lastDeviceEngine = m_deviceSinkEngines.back(); - delete lastDeviceEngine; + const DSPDeviceSinkEngine *lastDeviceEngine = m_deviceSinkEngines.back(); m_deviceSinkEngines.pop_back(); for (int i = 0; i < m_deviceEngineReferences.size(); i++) { if (m_deviceEngineReferences[i].m_deviceSinkEngine == lastDeviceEngine) { + QThread* deviceThread = m_deviceEngineReferences[i].m_thread; + deviceThread->exit(); + deviceThread->wait(); m_deviceEngineReferences.removeAt(i); break; } @@ -201,7 +222,9 @@ void DSPEngine::removeDeviceEngineAt(int deviceIndex) else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 1) // sink { DSPDeviceSinkEngine *deviceEngine = m_deviceEngineReferences[deviceIndex].m_deviceSinkEngine; - delete deviceEngine; + QThread *deviceThread = m_deviceEngineReferences[deviceIndex].m_thread; + deviceThread->exit(); + deviceThread->wait(); m_deviceSinkEngines.removeAll(deviceEngine); } else if (m_deviceEngineReferences[deviceIndex].m_deviceEngineType == 2) // MIMO diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index 05815feb1..e0386a05e 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -565,7 +565,6 @@ void MainWindow::sampleSourceCreate( void MainWindow::sampleSinkAdd(Workspace *deviceWorkspace, Workspace *spectrumWorkspace, int deviceIndex) { DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine(); - dspDeviceSinkEngine->start(); uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID(); char uidCStr[16]; @@ -993,7 +992,6 @@ void MainWindow::removeDeviceSet(int deviceSetIndex) if (deviceUISet->m_deviceSourceEngine) // source device { DSPDeviceSourceEngine *deviceEngine = deviceUISet->m_deviceSourceEngine; - deviceEngine->stopAcquistion(); deviceEngine->removeSink(deviceUISet->m_spectrumVis); // deletes old UI and core object @@ -1015,7 +1013,6 @@ void MainWindow::removeDeviceSet(int deviceSetIndex) else if (deviceUISet->m_deviceSinkEngine) // sink device { DSPDeviceSinkEngine *deviceEngine = deviceUISet->m_deviceSinkEngine; - deviceEngine->stopGeneration(); deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis); // deletes old UI and output object @@ -1023,24 +1020,19 @@ void MainWindow::removeDeviceSet(int deviceSetIndex) deviceUISet->m_deviceAPI->getSampleSink()->setMessageQueueToGUI(nullptr); // have sink stop sending messages to the GUI deviceUISet->m_deviceGUI->destroy(); deviceUISet->m_deviceAPI->resetSamplingDeviceId(); - deviceUISet->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( - deviceUISet->m_deviceAPI->getSampleSink()); deviceUISet->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists - DeviceAPI *sinkAPI = deviceUISet->m_deviceAPI; - delete deviceUISet; - - deviceEngine->stop(); m_dspEngine->removeDeviceEngineAt(deviceSetIndex); DeviceEnumerator::instance()->removeTxSelection(deviceSetIndex); + DeviceAPI *sinkAPI = deviceUISet->m_deviceAPI; + delete deviceUISet; + delete sinkAPI->getSampleSink(); delete sinkAPI; } else if (deviceUISet->m_deviceMIMOEngine) // MIMO device { DSPDeviceMIMOEngine *deviceEngine = deviceUISet->m_deviceMIMOEngine; - deviceEngine->stopProcess(1); // Tx side - deviceEngine->stopProcess(0); // Rx side deviceEngine->removeSpectrumSink(deviceUISet->m_spectrumVis); // deletes old UI and output object @@ -1096,7 +1088,6 @@ void MainWindow::removeLastDeviceSet() if (m_deviceUIs.back()->m_deviceSourceEngine) // source tab { DSPDeviceSourceEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSourceEngine; - lastDeviceEngine->stopAcquistion(); lastDeviceEngine->removeSink(m_deviceUIs.back()->m_spectrumVis); // deletes old UI and input object @@ -1116,7 +1107,6 @@ void MainWindow::removeLastDeviceSet() else if (m_deviceUIs.back()->m_deviceSinkEngine) // sink tab { DSPDeviceSinkEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceSinkEngine; - lastDeviceEngine->stopGeneration(); lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis); // deletes old UI and output object @@ -1136,8 +1126,6 @@ void MainWindow::removeLastDeviceSet() else if (m_deviceUIs.back()->m_deviceMIMOEngine) // MIMO tab { DSPDeviceMIMOEngine *lastDeviceEngine = m_deviceUIs.back()->m_deviceMIMOEngine; - lastDeviceEngine->stopProcess(1); // Tx side - lastDeviceEngine->stopProcess(0); // Rx side lastDeviceEngine->removeSpectrumSink(m_deviceUIs.back()->m_spectrumVis); // deletes old UI and output object diff --git a/sdrsrv/mainserver.cpp b/sdrsrv/mainserver.cpp index c98f5decd..da49095cd 100644 --- a/sdrsrv/mainserver.cpp +++ b/sdrsrv/mainserver.cpp @@ -270,7 +270,6 @@ void MainServer::applySettings() void MainServer::addSinkDevice() { DSPDeviceSinkEngine *dspDeviceSinkEngine = m_dspEngine->addDeviceSinkEngine(); - dspDeviceSinkEngine->start(); uint dspDeviceSinkEngineUID = dspDeviceSinkEngine->getUID(); char uidCStr[16]; @@ -398,7 +397,6 @@ void MainServer::removeLastDevice() if (m_mainCore->m_deviceSets.back()->m_deviceSourceEngine) // source set { DSPDeviceSourceEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSourceEngine; - lastDeviceEngine->stopAcquistion(); // deletes old UI and input object m_mainCore->m_deviceSets.back()->freeChannels(); // destroys the channel instances @@ -415,28 +413,22 @@ void MainServer::removeLastDevice() else if (m_mainCore->m_deviceSets.back()->m_deviceSinkEngine) // sink set { DSPDeviceSinkEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceSinkEngine; - lastDeviceEngine->stopGeneration(); // deletes old UI and output object m_mainCore->m_deviceSets.back()->freeChannels(); m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId(); - m_mainCore->m_deviceSets.back()->m_deviceAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( - m_mainCore->m_deviceSets.back()->m_deviceAPI->getSampleSink()); m_mainCore->m_deviceSets.back()->m_deviceAPI->clearBuddiesLists(); // clear old API buddies lists + m_dspEngine->removeLastDeviceSinkEngine(); + DeviceAPI *sinkAPI = m_mainCore->m_deviceSets.back()->m_deviceAPI; delete m_mainCore->m_deviceSets.back(); - - lastDeviceEngine->stop(); - m_dspEngine->removeLastDeviceSinkEngine(); - + delete sinkAPI->getSampleSink(); delete sinkAPI; } else if (m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine) // MIMO set { DSPDeviceMIMOEngine *lastDeviceEngine = m_mainCore->m_deviceSets.back()->m_deviceMIMOEngine; - lastDeviceEngine->stopProcess(1); // Tx side - lastDeviceEngine->stopProcess(0); // Rx side m_mainCore->m_deviceSets.back()->freeChannels(); m_mainCore->m_deviceSets.back()->m_deviceAPI->resetSamplingDeviceId();