From 585d806ef86f926c9e7a81a6c9144c3c1bdfa09a Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 21 Aug 2024 05:27:01 +0200 Subject: [PATCH] All device plugins: make sure start and stop are effective once only. PArt of #2159 --- .../samplemimo/bladerf2mimo/bladerf2mimo.cpp | 44 +++++++++++-------- .../samplemimo/limesdrmimo/limesdrmimo.cpp | 44 +++++++++++-------- .../samplemimo/plutosdrmimo/plutosdrmimo.cpp | 44 +++++++++++-------- plugins/samplemimo/testmi/testmi.cpp | 2 +- plugins/samplemimo/xtrxmimo/xtrxmimo.cpp | 44 +++++++++++-------- .../bladerf1output/bladerf1output.cpp | 38 +++++++++------- plugins/samplesink/fileoutput/fileoutput.cpp | 15 ++++++- plugins/samplesink/fileoutput/fileoutput.h | 1 + .../samplesink/hackrfoutput/hackrfoutput.cpp | 21 +++++---- .../limesdroutput/limesdroutput.cpp | 23 ++++++---- .../plutosdroutput/plutosdroutput.cpp | 25 +++++++---- .../samplesink/remoteoutput/remoteoutput.cpp | 17 ++++++- .../samplesink/remoteoutput/remoteoutput.h | 3 +- .../soapysdroutput/soapysdroutput.cpp | 10 ++++- plugins/samplesink/usrpoutput/usrpoutput.cpp | 16 +++++-- plugins/samplesink/xtrxoutput/xtrxoutput.cpp | 19 +++++--- plugins/samplesource/airspy/airspyinput.cpp | 14 +++--- plugins/samplesource/airspy/airspyinput.h | 2 +- .../samplesource/airspyhf/airspyhfinput.cpp | 23 ++++++---- plugins/samplesource/airspyhf/airspyhfinput.h | 2 +- .../bladerf1input/bladerf1input.cpp | 28 +++++++----- .../bladerf1input/bladerf1input.h | 2 +- .../bladerf2input/bladerf2input.cpp | 12 +++-- plugins/samplesource/fcdpro/fcdproinput.cpp | 23 ++++++---- .../fcdproplus/fcdproplusinput.cpp | 18 +++++--- .../samplesource/hackrfinput/hackrfinput.cpp | 32 ++++++++------ .../samplesource/hackrfinput/hackrfinput.h | 2 +- .../limesdrinput/limesdrinput.cpp | 27 ++++++++---- .../samplesource/limesdrinput/limesdrinput.h | 2 +- .../plutosdrinput/plutosdrinput.cpp | 25 +++++++---- plugins/samplesource/sdrplay/sdrplayinput.cpp | 25 ++++++----- plugins/samplesource/sdrplay/sdrplayinput.h | 2 +- .../samplesource/sdrplayv3/sdrplayv3input.cpp | 21 ++++++--- .../samplesource/sdrplayv3/sdrplayv3input.h | 2 +- .../sigmffileinput/sigmffileinput.cpp | 17 ++++++- .../sigmffileinput/sigmffileinput.h | 1 + .../soapysdrinput/soapysdrinput.cpp | 9 +++- .../testsource/testsourceinput.cpp | 7 ++- plugins/samplesource/usrpinput/usrpinput.cpp | 19 +++++--- plugins/samplesource/xtrxinput/xtrxinput.cpp | 14 ++++-- 40 files changed, 453 insertions(+), 242 deletions(-) diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mimo.cpp b/plugins/samplemimo/bladerf2mimo/bladerf2mimo.cpp index 015f46ca14..e7c1591d75 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mimo.cpp +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mimo.cpp @@ -142,6 +142,12 @@ void BladeRF2MIMO::init() bool BladeRF2MIMO::startRx() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_runningRx) { + return true; + } + qDebug("BladeRF2MIMO::startRx"); if (!m_open) @@ -150,12 +156,6 @@ bool BladeRF2MIMO::startRx() return false; } - QMutexLocker mutexLocker(&m_mutex); - - if (m_runningRx) { - stopRx(); - } - m_sourceThread = new BladeRF2MIThread(m_dev->getDev()); m_sampleMIFifo.reset(); m_sourceThread->setFifo(&m_sampleMIFifo); @@ -178,6 +178,12 @@ bool BladeRF2MIMO::startRx() bool BladeRF2MIMO::startTx() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_runningTx) { + return true; + } + qDebug("BladeRF2MIMO::startTx"); if (!m_open) @@ -186,12 +192,6 @@ bool BladeRF2MIMO::startTx() return false; } - QMutexLocker mutexLocker(&m_mutex); - - if (m_runningTx) { - stopTx(); - } - m_sinkThread = new BladeRF2MOThread(m_dev->getDev()); m_sampleMOFifo.reset(); m_sinkThread->setFifo(&m_sampleMOFifo); @@ -213,18 +213,22 @@ bool BladeRF2MIMO::startTx() void BladeRF2MIMO::stopRx() { - qDebug("BladeRF2MIMO::stopRx"); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_runningRx) { + return; + } if (!m_sourceThread) { return; } - QMutexLocker mutexLocker(&m_mutex); + qDebug("BladeRF2MIMO::stopRx"); + m_runningRx = false; m_sourceThread->stopWork(); delete m_sourceThread; m_sourceThread = nullptr; - m_runningRx = false; for (int i = 0; i < 2; i++) { m_dev->closeRx(i); @@ -233,18 +237,22 @@ void BladeRF2MIMO::stopRx() void BladeRF2MIMO::stopTx() { - qDebug("BladeRF2MIMO::stopTx"); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_runningTx) { + return; + } if (!m_sinkThread) { return; } - QMutexLocker mutexLocker(&m_mutex); + qDebug("BladeRF2MIMO::stopTx"); + m_runningTx = false; m_sinkThread->stopWork(); delete m_sinkThread; m_sinkThread = nullptr; - m_runningTx = false; for (int i = 0; i < 2; i++) { m_dev->closeTx(i); diff --git a/plugins/samplemimo/limesdrmimo/limesdrmimo.cpp b/plugins/samplemimo/limesdrmimo/limesdrmimo.cpp index c78f86975f..1686cfa6f9 100644 --- a/plugins/samplemimo/limesdrmimo/limesdrmimo.cpp +++ b/plugins/samplemimo/limesdrmimo/limesdrmimo.cpp @@ -256,6 +256,12 @@ void LimeSDRMIMO::init() bool LimeSDRMIMO::startRx() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_runningRx) { + return true; + } + qDebug("LimeSDRMIMO::startRx"); lms_stream_t *streams[2]; @@ -265,12 +271,6 @@ bool LimeSDRMIMO::startRx() return false; } - QMutexLocker mutexLocker(&m_mutex); - - if (m_runningRx) { - stopRx(); - } - for (unsigned int channel = 0; channel < 2; channel++) { if (channel < m_deviceAPI->getNbSourceStreams()) @@ -307,18 +307,22 @@ bool LimeSDRMIMO::startRx() void LimeSDRMIMO::stopRx() { - qDebug("LimeSDRMIMO::stopRx"); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_runningRx) { + return; + } if (!m_sourceThread) { return; } - QMutexLocker mutexLocker(&m_mutex); + qDebug("LimeSDRMIMO::stopRx"); + m_runningRx = false; m_sourceThread->stopWork(); delete m_sourceThread; m_sourceThread = nullptr; - m_runningRx = false; for (unsigned int channel = 0; channel < 2; channel++) { @@ -330,6 +334,12 @@ void LimeSDRMIMO::stopRx() bool LimeSDRMIMO::startTx() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_runningTx) { + return true; + } + qDebug("LimeSDRMIMO::startTx"); lms_stream_t *streams[2]; @@ -339,12 +349,6 @@ bool LimeSDRMIMO::startTx() return false; } - QMutexLocker mutexLocker(&m_mutex); - - if (m_runningTx) { - stopTx(); - } - for (unsigned int channel = 0; channel < 2; channel++) { if (channel < m_deviceAPI->getNbSinkStreams()) @@ -380,18 +384,22 @@ bool LimeSDRMIMO::startTx() void LimeSDRMIMO::stopTx() { - qDebug("LimeSDRMIMO::stopTx"); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_runningTx) { + return; + } if (!m_sinkThread) { return; } - QMutexLocker mutexLocker(&m_mutex); + qDebug("LimeSDRMIMO::stopTx"); + m_runningTx = false; m_sinkThread->stopWork(); delete m_sinkThread; m_sinkThread = nullptr; - m_runningTx = false; for (unsigned int channel = 0; channel < 2; channel++) { diff --git a/plugins/samplemimo/plutosdrmimo/plutosdrmimo.cpp b/plugins/samplemimo/plutosdrmimo/plutosdrmimo.cpp index 433b2dcb92..0c50165722 100644 --- a/plugins/samplemimo/plutosdrmimo/plutosdrmimo.cpp +++ b/plugins/samplemimo/plutosdrmimo/plutosdrmimo.cpp @@ -168,7 +168,11 @@ void PlutoSDRMIMO::init() bool PlutoSDRMIMO::startRx() { - qDebug("PlutoSDRMIMO::startRx"); + QMutexLocker mutexLocker(&m_mutex); + + if (m_runningRx) { + return true; + } if (!m_open) { @@ -176,11 +180,7 @@ bool PlutoSDRMIMO::startRx() return false; } - QMutexLocker mutexLocker(&m_mutex); - - if (m_runningRx) { - stopRx(); - } + qDebug("PlutoSDRMIMO::startRx"); m_sourceThread = new PlutoSDRMIThread(m_plutoParams->getBox()); m_sampleMIFifo.reset(); @@ -206,7 +206,11 @@ bool PlutoSDRMIMO::startRx() bool PlutoSDRMIMO::startTx() { - qDebug("PlutoSDRMIMO::startTx"); + QMutexLocker mutexLocker(&m_mutex); + + if (m_runningTx) { + return true; + } if (!m_open) { @@ -214,11 +218,7 @@ bool PlutoSDRMIMO::startTx() return false; } - QMutexLocker mutexLocker(&m_mutex); - - if (m_runningTx) { - stopTx(); - } + qDebug("PlutoSDRMIMO::startTx"); m_sinkThread = new PlutoSDRMOThread(m_plutoParams->getBox()); m_sampleMOFifo.reset(); @@ -243,18 +243,22 @@ bool PlutoSDRMIMO::startTx() void PlutoSDRMIMO::stopRx() { - qDebug("PlutoSDRMIMO::stopRx"); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_runningRx) { + return; + } if (!m_sourceThread) { return; } - QMutexLocker mutexLocker(&m_mutex); + qDebug("PlutoSDRMIMO::stopRx"); + m_runningRx = false; m_sourceThread->stopWork(); delete m_sourceThread; m_sourceThread = nullptr; - m_runningRx = false; if (m_nbRx > 1) { m_plutoParams->getBox()->closeSecondRx(); @@ -270,18 +274,22 @@ void PlutoSDRMIMO::stopRx() void PlutoSDRMIMO::stopTx() { - qDebug("PlutoSDRMIMO::stopTx"); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_runningTx) { + return; + } if (!m_sinkThread) { return; } - QMutexLocker mutexLocker(&m_mutex); + qDebug("PlutoSDRMIMO::stopTx"); + m_runningTx = false; m_sinkThread->stopWork(); delete m_sinkThread; m_sinkThread = nullptr; - m_runningTx = false; if (m_nbTx > 1) { m_plutoParams->getBox()->closeSecondTx(); diff --git a/plugins/samplemimo/testmi/testmi.cpp b/plugins/samplemimo/testmi/testmi.cpp index 92985611c0..28d63e12b4 100644 --- a/plugins/samplemimo/testmi/testmi.cpp +++ b/plugins/samplemimo/testmi/testmi.cpp @@ -127,7 +127,7 @@ void TestMI::stopRx() } qDebug("TestMI::stopRx"); - m_running = false; + m_running = false; stopWorkers(); m_testSourceWorkers.clear(); diff --git a/plugins/samplemimo/xtrxmimo/xtrxmimo.cpp b/plugins/samplemimo/xtrxmimo/xtrxmimo.cpp index 937a62c9c0..c4a0ba32e7 100644 --- a/plugins/samplemimo/xtrxmimo/xtrxmimo.cpp +++ b/plugins/samplemimo/xtrxmimo/xtrxmimo.cpp @@ -124,7 +124,11 @@ void XTRXMIMO::init() bool XTRXMIMO::startRx() { - qDebug("XTRXMIMO::startRx"); + QMutexLocker mutexLocker(&m_mutex); + + if (m_runningRx) { + return true; + } if (!m_open) { @@ -132,11 +136,7 @@ bool XTRXMIMO::startRx() return false; } - QMutexLocker mutexLocker(&m_mutex); - - if (m_runningRx) { - stopRx(); - } + qDebug("XTRXMIMO::startRx"); m_sourceThread = new XTRXMIThread(m_deviceShared.m_dev->getDevice()); m_sampleMIFifo.reset(); @@ -152,7 +152,11 @@ bool XTRXMIMO::startRx() bool XTRXMIMO::startTx() { - qDebug("XTRXMIMO::startTx"); + QMutexLocker mutexLocker(&m_mutex); + + if (m_runningTx) { + return true; + } if (!m_open) { @@ -160,11 +164,7 @@ bool XTRXMIMO::startTx() return false; } - QMutexLocker mutexLocker(&m_mutex); - - if (m_runningRx) { - stopRx(); - } + qDebug("XTRXMIMO::startTx"); m_sinkThread = new XTRXMOThread(m_deviceShared.m_dev->getDevice()); m_sampleMOFifo.reset(); @@ -179,34 +179,42 @@ bool XTRXMIMO::startTx() void XTRXMIMO::stopRx() { - qDebug("XTRXMIMO::stopRx"); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_runningRx){ + return; + } if (!m_sourceThread) { return; } - QMutexLocker mutexLocker(&m_mutex); + qDebug("XTRXMIMO::stopRx"); + m_runningRx = false; m_sourceThread->stopWork(); delete m_sourceThread; m_sourceThread = nullptr; - m_runningRx = false; } void XTRXMIMO::stopTx() { - qDebug("XTRXMIMO::stopTx"); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_runningTx) { + return; + } if (!m_sinkThread) { return; } - QMutexLocker mutexLocker(&m_mutex); + qDebug("XTRXMIMO::stopTx"); + m_runningTx = false; m_sinkThread->stopWork(); delete m_sinkThread; m_sinkThread = nullptr; - m_runningTx = false; } QByteArray XTRXMIMO::serialize() const diff --git a/plugins/samplesink/bladerf1output/bladerf1output.cpp b/plugins/samplesink/bladerf1output/bladerf1output.cpp index 04eb83a1ae..df7a634eeb 100644 --- a/plugins/samplesink/bladerf1output/bladerf1output.cpp +++ b/plugins/samplesink/bladerf1output/bladerf1output.cpp @@ -144,25 +144,24 @@ void Bladerf1Output::init() bool Bladerf1Output::start() { -// QMutexLocker mutexLocker(&m_mutex); + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_dev) { return false; } - if (m_running) stop(); - m_bladerfThread = new Bladerf1OutputThread(m_dev, &m_sampleSourceFifo); - -// mutexLocker.unlock(); - applySettings(m_settings, QList(), true); - m_bladerfThread->setLog2Interpolation(m_settings.m_log2Interp); - m_bladerfThread->startWork(); - qDebug("BladerfOutput::start: started"); m_running = true; + mutexLocker.unlock(); + + applySettings(m_settings, QList(), true); return true; } @@ -171,7 +170,7 @@ void Bladerf1Output::closeDevice() { int res; - if (m_dev == 0) { // was never open + if (m_dev == nullptr) { // was never open return; } @@ -180,7 +179,7 @@ void Bladerf1Output::closeDevice() qCritical("BladerfOutput::closeDevice: bladerf_enable_module with return code %d", res); } - if (m_deviceAPI->getSourceBuddies().size() == 0) + if (m_deviceAPI->getSourceBuddies().empty()) { qDebug("BladerfOutput::closeDevice: closing device since Rx side is not open"); @@ -190,21 +189,26 @@ void Bladerf1Output::closeDevice() } } - m_sharedParams.m_dev = 0; + m_sharedParams.m_dev = nullptr; m_dev = 0; } void Bladerf1Output::stop() { -// QMutexLocker mutexLocker(&m_mutex); - if (m_bladerfThread != 0) + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + + m_running = false; + + if (m_bladerfThread) { m_bladerfThread->stopWork(); delete m_bladerfThread; - m_bladerfThread = 0; + m_bladerfThread = nullptr; } - - m_running = false; } QByteArray Bladerf1Output::serialize() const diff --git a/plugins/samplesink/fileoutput/fileoutput.cpp b/plugins/samplesink/fileoutput/fileoutput.cpp index f8a479802c..83034f8a35 100644 --- a/plugins/samplesink/fileoutput/fileoutput.cpp +++ b/plugins/samplesink/fileoutput/fileoutput.cpp @@ -44,6 +44,7 @@ MESSAGE_CLASS_DEFINITION(FileOutput::MsgReportFileOutputStreamTiming, Message) FileOutput::FileOutput(DeviceAPI *deviceAPI) : m_deviceAPI(deviceAPI), + m_running(false), m_settings(), m_fileOutputWorker(nullptr), m_deviceDescription("FileOutput"), @@ -94,6 +95,11 @@ void FileOutput::init() bool FileOutput::start() { QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } + qDebug() << "FileOutput::start"; openFileStream(); @@ -104,6 +110,7 @@ bool FileOutput::start() m_fileOutputWorker->setLog2Interpolation(m_settings.m_log2Interp); m_fileOutputWorker->connectTimer(m_masterTimer); startWorker(); + m_running = true; mutexLocker.unlock(); //applySettings(m_generalSettings, m_settings, true); @@ -120,9 +127,15 @@ bool FileOutput::start() void FileOutput::stop() { - qDebug() << "FileSourceInput::stop"; QMutexLocker mutexLocker(&m_mutex); + if (!m_running) { + return; + } + + qDebug() << "FileSourceInput::stop"; + m_running = false; + if (m_fileOutputWorker) { stopWorker(); diff --git a/plugins/samplesink/fileoutput/fileoutput.h b/plugins/samplesink/fileoutput/fileoutput.h index 0678279dc3..8c4847d964 100644 --- a/plugins/samplesink/fileoutput/fileoutput.h +++ b/plugins/samplesink/fileoutput/fileoutput.h @@ -234,6 +234,7 @@ class FileOutput : public DeviceSampleSink { private: DeviceAPI *m_deviceAPI; QMutex m_mutex; + bool m_running; FileOutputSettings m_settings; std::ofstream m_ofstream; FileOutputWorker* m_fileOutputWorker; diff --git a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp index ad1adb4015..409ca2e453 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp @@ -129,27 +129,28 @@ void HackRFOutput::init() bool HackRFOutput::start() { + QMutexLocker mutexLocker(&m_mutex); + if (!m_dev) { return false; } if (m_running) { - stop(); + return true; } m_hackRFThread = new HackRFOutputThread(m_dev, &m_sampleSourceFifo); -// mutexLocker.unlock(); - - applySettings(m_settings, QList(), true); m_hackRFThread->setLog2Interpolation(m_settings.m_log2Interp); m_hackRFThread->setFcPos((int) m_settings.m_fcPos); m_hackRFThread->startWork(); + m_running = true; + mutexLocker.unlock(); qDebug("HackRFOutput::start: started"); - m_running = true; + applySettings(m_settings, QList(), true); return true; } @@ -173,8 +174,14 @@ void HackRFOutput::closeDevice() void HackRFOutput::stop() { + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + qDebug("HackRFOutput::stop"); -// QMutexLocker mutexLocker(&m_mutex); + m_running = false; if(m_hackRFThread != 0) { @@ -182,8 +189,6 @@ void HackRFOutput::stop() delete m_hackRFThread; m_hackRFThread = 0; } - - m_running = false; } QByteArray HackRFOutput::serialize() const diff --git a/plugins/samplesink/limesdroutput/limesdroutput.cpp b/plugins/samplesink/limesdroutput/limesdroutput.cpp index be4d95fa11..9551a18df5 100644 --- a/plugins/samplesink/limesdroutput/limesdroutput.cpp +++ b/plugins/samplesink/limesdroutput/limesdroutput.cpp @@ -380,14 +380,17 @@ void LimeSDROutput::init() bool LimeSDROutput::start() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } + if (!m_deviceShared.m_deviceParams->getDevice()) { return false; } - if (m_running) { stop(); } - - if (!acquireChannel()) - { + if (!acquireChannel()) { return false; } @@ -396,20 +399,25 @@ bool LimeSDROutput::start() m_limeSDROutputThread = new LimeSDROutputThread(&m_streamId, &m_sampleSourceFifo); qDebug("LimeSDROutput::start: thread created"); - applySettings(m_settings, QList(), true); - m_limeSDROutputThread->setLog2Interpolation(m_settings.m_log2SoftInterp); m_limeSDROutputThread->startWork(); - m_deviceShared.m_thread = m_limeSDROutputThread; m_running = true; + mutexLocker.unlock(); + + applySettings(m_settings, QList(), true); return true; } void LimeSDROutput::stop() { + if (!m_running) { + return; + } + qDebug("LimeSDROutput::stop"); + m_running = false; if (m_limeSDROutputThread) { @@ -419,7 +427,6 @@ void LimeSDROutput::stop() } m_deviceShared.m_thread = 0; - m_running = false; releaseChannel(); } diff --git a/plugins/samplesink/plutosdroutput/plutosdroutput.cpp b/plugins/samplesink/plutosdroutput/plutosdroutput.cpp index 56b62d83ff..3a3dba6250 100644 --- a/plugins/samplesink/plutosdroutput/plutosdroutput.cpp +++ b/plugins/samplesink/plutosdroutput/plutosdroutput.cpp @@ -102,34 +102,44 @@ void PlutoSDROutput::init() bool PlutoSDROutput::start() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } + if (!m_deviceShared.m_deviceParams->getBox()) { qCritical("PlutoSDROutput::start: device not open"); return false; } - if (m_running) { - stop(); - } - // start / stop streaming is done in the thread. m_plutoSDROutputThread = new PlutoSDROutputThread(PLUTOSDR_BLOCKSIZE_SAMPLES, m_deviceShared.m_deviceParams->getBox(), &m_sampleSourceFifo); qDebug("PlutoSDROutput::start: thread created"); - applySettings(m_settings, QList(), true); - m_plutoSDROutputThread->setLog2Interpolation(m_settings.m_log2Interp); m_plutoSDROutputThread->startWork(); - m_deviceShared.m_thread = m_plutoSDROutputThread; m_running = true; + mutexLocker.unlock(); + + applySettings(m_settings, QList(), true); return true; } void PlutoSDROutput::stop() { + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + + m_running = false; + if (m_plutoSDROutputThread != 0) { m_plutoSDROutputThread->stopWork(); @@ -138,7 +148,6 @@ void PlutoSDROutput::stop() } m_deviceShared.m_thread = 0; - m_running = false; } QByteArray PlutoSDROutput::serialize() const diff --git a/plugins/samplesink/remoteoutput/remoteoutput.cpp b/plugins/samplesink/remoteoutput/remoteoutput.cpp index 2abd3775a7..6bffe0e5c6 100644 --- a/plugins/samplesink/remoteoutput/remoteoutput.cpp +++ b/plugins/samplesink/remoteoutput/remoteoutput.cpp @@ -47,6 +47,7 @@ MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgRequestFixedData, Message) RemoteOutput::RemoteOutput(DeviceAPI *deviceAPI) : m_deviceAPI(deviceAPI), + m_running(false), m_settings(), m_centerFrequency(435000000), m_sampleRate(48000), @@ -95,6 +96,11 @@ void RemoteOutput::destroy() bool RemoteOutput::start() { QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } + qDebug() << "RemoteOutput::start"; m_remoteOutputWorker = new RemoteOutputWorker(&m_sampleSourceFifo); @@ -105,6 +111,7 @@ bool RemoteOutput::start() m_remoteOutputWorker->setNbBlocksFEC(m_settings.m_nbFECBlocks); m_remoteOutputWorker->connectTimer(m_masterTimer); startWorker(); + m_running = true; mutexLocker.unlock(); applySampleRate(); @@ -121,12 +128,18 @@ void RemoteOutput::init() void RemoteOutput::stop() { - qDebug() << "RemoteOutput::stop"; QMutexLocker mutexLocker(&m_mutex); + if (!m_running) { + return; + } + + qDebug() << "RemoteOutput::stop"; + m_running = false; + if (m_remoteOutputWorker) { - stopWorker(); + stopWorker(); delete m_remoteOutputWorker; m_remoteOutputWorker = nullptr; } diff --git a/plugins/samplesink/remoteoutput/remoteoutput.h b/plugins/samplesink/remoteoutput/remoteoutput.h index 522d042272..434e2916d3 100644 --- a/plugins/samplesink/remoteoutput/remoteoutput.h +++ b/plugins/samplesink/remoteoutput/remoteoutput.h @@ -258,7 +258,8 @@ class RemoteOutput : public DeviceSampleSink { private: DeviceAPI *m_deviceAPI; - QMutex m_mutex; + QRecursiveMutex m_mutex; + bool m_running; RemoteOutputSettings m_settings; uint64_t m_centerFrequency; int m_sampleRate; diff --git a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp index 43aa7f2d5a..99d845941e 100644 --- a/plugins/samplesink/soapysdroutput/soapysdroutput.cpp +++ b/plugins/samplesink/soapysdroutput/soapysdroutput.cpp @@ -453,6 +453,11 @@ bool SoapySDROutput::start() // // Note: this is quite similar to the BladeRF2 start handling. The main difference is that the channel allocation (enabling) process is // done in the thread object. + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_openSuccess) { @@ -558,11 +563,13 @@ void SoapySDROutput::stop() // channel then the FIFO reference is simply removed from the thread so that this FIFO will not be used anymore. // In this case the channel is not closed (this is managed in the thread object) so that other channels can continue with the // same configuration. The device continues streaming on this channel but the samples are set to all zeros. + QMutexLocker mutexLocker(&m_mutex); if (!m_running) { return; } + m_running = false; int requestedChannel = m_deviceAPI->getDeviceItemIndex(); SoapySDROutputThread *soapySDROutputThread = findThread(); @@ -648,9 +655,8 @@ void SoapySDROutput::stop() soapySDROutputThread->setFifo(requestedChannel, nullptr); // remove FIFO } + mutexLocker.unlock(); applySettings(m_settings, true); // re-apply forcibly to set sample rate with the new number of channels - - m_running = false; } QByteArray SoapySDROutput::serialize() const diff --git a/plugins/samplesink/usrpoutput/usrpoutput.cpp b/plugins/samplesink/usrpoutput/usrpoutput.cpp index fdd9890315..8f9444e8ac 100644 --- a/plugins/samplesink/usrpoutput/usrpoutput.cpp +++ b/plugins/samplesink/usrpoutput/usrpoutput.cpp @@ -379,12 +379,16 @@ void USRPOutput::init() bool USRPOutput::start() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } + if (!m_deviceShared.m_deviceParams->getDevice()) { return false; } - if (m_running) { stop(); } - if (!acquireChannel()) { return false; } @@ -403,7 +407,14 @@ bool USRPOutput::start() void USRPOutput::stop() { + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + qDebug("USRPOutput::stop"); + m_running = false; if (m_usrpOutputThread) { @@ -413,7 +424,6 @@ void USRPOutput::stop() } m_deviceShared.m_thread = 0; - m_running = false; releaseChannel(); } diff --git a/plugins/samplesink/xtrxoutput/xtrxoutput.cpp b/plugins/samplesink/xtrxoutput/xtrxoutput.cpp index d9aac937e4..5eacc52c70 100644 --- a/plugins/samplesink/xtrxoutput/xtrxoutput.cpp +++ b/plugins/samplesink/xtrxoutput/xtrxoutput.cpp @@ -265,6 +265,11 @@ bool XTRXOutput::start() // // Eventually it registers the FIFO in the thread. If the thread has to be started it enables the channels up to the number of channels // allocated in the thread and starts the thread. + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_deviceShared.m_dev || !m_deviceShared.m_dev->getDevice()) { @@ -341,6 +346,8 @@ bool XTRXOutput::start() xtrxOutputThread->setFifo(requestedChannel, &m_sampleSourceFifo); xtrxOutputThread->setLog2Interpolation(requestedChannel, m_settings.m_log2SoftInterp); + m_running = true; + mutexLocker.unlock(); applySettings(m_settings, QList(), true); @@ -351,7 +358,6 @@ bool XTRXOutput::start() } qDebug("XTRXOutput::start: started"); - m_running = true; return true; } @@ -366,16 +372,18 @@ void XTRXOutput::stop() // If the thread is currently managing both channels (MO mode) then we are removing one channel. Thus we must // transition from MO to SO. This transition is handled by stopping the thread, deleting it and creating a new one // managing a single channel. + QMutexLocker mutexLocker(&m_mutex); if (!m_running) { return; } + m_running = false; int removedChannel = m_deviceAPI->getDeviceItemIndex(); // channel to remove int requestedChannel = removedChannel ^ 1; // channel to keep (opposite channel) XTRXOutputThread *xtrxOutputThread = findThread(); - if (xtrxOutputThread == 0) { // no thread allocated + if (xtrxOutputThread == nullptr) { // no thread allocated return; } @@ -386,8 +394,8 @@ void XTRXOutput::stop() qDebug("XTRXOutput::stop: SO mode. Just stop and delete the thread"); xtrxOutputThread->stopWork(); delete xtrxOutputThread; - m_XTRXOutputThread = 0; - m_deviceShared.m_thread = 0; + m_XTRXOutputThread = nullptr; + m_deviceShared.m_thread = nullptr; // remove old thread address from buddies (reset in all buddies) const std::vector& sinkBuddies = m_deviceAPI->getSinkBuddies(); @@ -417,11 +425,10 @@ void XTRXOutput::stop() ((DeviceXTRXShared*) (*it)->getBuddySharedPtr())->m_sink->setThread(nullptr); } + mutexLocker.unlock(); applySettings(m_settings, QList(), true); xtrxOutputThread->startWork(); } - - m_running = false; } void XTRXOutput::suspendRxThread() diff --git a/plugins/samplesource/airspy/airspyinput.cpp b/plugins/samplesource/airspy/airspyinput.cpp index 26f04ef19e..f9abf8bd13 100644 --- a/plugins/samplesource/airspy/airspyinput.cpp +++ b/plugins/samplesource/airspy/airspyinput.cpp @@ -197,14 +197,14 @@ bool AirspyInput::start() { QMutexLocker mutexLocker(&m_mutex); - if (!m_dev) { - return false; - } - if (m_running) { return true; } + if (!m_dev) { + return false; + } + m_airspyWorkerThread = new QThread(); m_airspyWorker = new AirspyWorker(m_dev, &m_sampleFifo); m_airspyWorker->moveToThread(m_airspyWorkerThread); @@ -217,13 +217,13 @@ bool AirspyInput::start() m_airspyWorker->setLog2Decimation(m_settings.m_log2Decim); m_airspyWorker->setIQOrder(m_settings.m_iqOrder); m_airspyWorker->setFcPos((int) m_settings.m_fcPos); - mutexLocker.unlock(); - m_airspyWorkerThread->start(); + m_running = true; + + mutexLocker.unlock(); qDebug("AirspyInput::startInput: started"); applySettings(m_settings, QList(), true); - m_running = true; return true; } diff --git a/plugins/samplesource/airspy/airspyinput.h b/plugins/samplesource/airspy/airspyinput.h index fc57a23a84..12d66b2f60 100644 --- a/plugins/samplesource/airspy/airspyinput.h +++ b/plugins/samplesource/airspy/airspyinput.h @@ -141,7 +141,7 @@ class AirspyInput : public DeviceSampleSource { private: DeviceAPI *m_deviceAPI; - QMutex m_mutex; + QRecursiveMutex m_mutex; AirspySettings m_settings; struct airspy_device* m_dev; AirspyWorker* m_airspyWorker; diff --git a/plugins/samplesource/airspyhf/airspyhfinput.cpp b/plugins/samplesource/airspyhf/airspyhfinput.cpp index 7bc5067ec1..efc5f6898d 100644 --- a/plugins/samplesource/airspyhf/airspyhfinput.cpp +++ b/plugins/samplesource/airspyhf/airspyhfinput.cpp @@ -171,12 +171,12 @@ bool AirspyHFInput::start() { QMutexLocker mutexLocker(&m_mutex); - if (!m_dev) { - return false; + if (m_running) { + return true; } - if (m_running) { - stop(); + if (!m_dev) { + return false; } m_airspyHFWorkerThread = new QThread(); @@ -198,13 +198,13 @@ bool AirspyHFInput::start() m_airspyHFWorker->setLog2Decimation(m_settings.m_log2Decim); m_airspyHFWorker->setIQOrder(m_settings.m_iqOrder); - mutexLocker.unlock(); - m_airspyHFWorkerThread->start(); + m_running = true; + + mutexLocker.unlock(); qDebug("AirspyHFInput::startInput: started"); applySettings(m_settings, QList(), true); - m_running = true; return m_running; } @@ -223,9 +223,15 @@ void AirspyHFInput::closeDevice() void AirspyHFInput::stop() { - qDebug("AirspyHFInput::stop"); QMutexLocker mutexLocker(&m_mutex); + if (!m_running) { + return; + } + + qDebug("AirspyHFInput::stop"); + m_running = false; + if (m_airspyHFWorkerThread) { m_airspyHFWorkerThread->quit(); @@ -234,7 +240,6 @@ void AirspyHFInput::stop() m_airspyHFWorker = nullptr; } - m_running = false; } QByteArray AirspyHFInput::serialize() const diff --git a/plugins/samplesource/airspyhf/airspyhfinput.h b/plugins/samplesource/airspyhf/airspyhfinput.h index 3f1c9ec0d9..85325a349b 100644 --- a/plugins/samplesource/airspyhf/airspyhfinput.h +++ b/plugins/samplesource/airspyhf/airspyhfinput.h @@ -165,7 +165,7 @@ class AirspyHFInput : public DeviceSampleSource { private: DeviceAPI *m_deviceAPI; - QMutex m_mutex; + QRecursiveMutex m_mutex; AirspyHFSettings m_settings; airspyhf_device_t* m_dev; AirspyHFWorker* m_airspyHFWorker; diff --git a/plugins/samplesource/bladerf1input/bladerf1input.cpp b/plugins/samplesource/bladerf1input/bladerf1input.cpp index ad284afd1c..8d4e24b916 100644 --- a/plugins/samplesource/bladerf1input/bladerf1input.cpp +++ b/plugins/samplesource/bladerf1input/bladerf1input.cpp @@ -151,7 +151,11 @@ void Bladerf1Input::init() bool Bladerf1Input::start() { -// QMutexLocker mutexLocker(&m_mutex); + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_dev) { @@ -159,20 +163,17 @@ bool Bladerf1Input::start() return false; } - if (m_running) stop(); - m_bladerfThread = new Bladerf1InputThread(m_dev, &m_sampleFifo); m_bladerfThread->setLog2Decimation(m_settings.m_log2Decim); m_bladerfThread->setFcPos((int) m_settings.m_fcPos); m_bladerfThread->setIQOrder(m_settings.m_iqOrder); - m_bladerfThread->startWork(); + m_running = true; -// mutexLocker.unlock(); + mutexLocker.unlock(); applySettings(m_settings, QList(), true); qDebug("BladerfInput::startInput: started"); - m_running = true; return true; } @@ -194,19 +195,25 @@ void Bladerf1Input::closeDevice() { qDebug("BladerfInput::closeDevice: closing device since Tx side is not open"); - if(m_dev != 0) // close BladeRF + if(m_dev != nullptr) // close BladeRF { bladerf_close(m_dev); } } - m_sharedParams.m_dev = 0; - m_dev = 0; + m_sharedParams.m_dev = nullptr; + m_dev = nullptr; } void Bladerf1Input::stop() { -// QMutexLocker mutexLocker(&m_mutex); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + + m_running = false; if(m_bladerfThread) { @@ -215,7 +222,6 @@ void Bladerf1Input::stop() m_bladerfThread = nullptr; } - m_running = false; } QByteArray Bladerf1Input::serialize() const diff --git a/plugins/samplesource/bladerf1input/bladerf1input.h b/plugins/samplesource/bladerf1input/bladerf1input.h index 6d95f3c529..3b20bd16cd 100644 --- a/plugins/samplesource/bladerf1input/bladerf1input.h +++ b/plugins/samplesource/bladerf1input/bladerf1input.h @@ -135,7 +135,7 @@ class Bladerf1Input : public DeviceSampleSource { private: DeviceAPI *m_deviceAPI; - QMutex m_mutex; + QRecursiveMutex m_mutex; BladeRF1InputSettings m_settings; struct bladerf* m_dev; Bladerf1InputThread* m_bladerfThread; diff --git a/plugins/samplesource/bladerf2input/bladerf2input.cpp b/plugins/samplesource/bladerf2input/bladerf2input.cpp index 9aa313132b..b3dd2c4f3f 100644 --- a/plugins/samplesource/bladerf2input/bladerf2input.cpp +++ b/plugins/samplesource/bladerf2input/bladerf2input.cpp @@ -290,6 +290,11 @@ bool BladeRF2Input::start() // // Eventually it registers the FIFO in the thread. If the thread has to be started it enables the channels up to the number of channels // allocated in the thread and starts the thread. + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_deviceShared.m_dev) { @@ -383,10 +388,11 @@ bool BladeRF2Input::start() bladerf2InputThread->startWork(); } + m_running = true; + mutexLocker.unlock(); applySettings(m_settings, QList(), true); qDebug("BladeRF2Input::start: started"); - m_running = true; return true; } @@ -408,6 +414,7 @@ void BladeRF2Input::stop() // anymore. In this case the channel is not closed (disabled) so that other channels can continue with the // same configuration. The device continues streaming on this channel but the samples are simply dropped (by // removing FIFO reference). + QMutexLocker mutexLocker(&m_mutex); if (!m_running) { return; @@ -420,6 +427,7 @@ void BladeRF2Input::stop() return; } + m_running = false; int nbOriginalChannels = bladerf2InputThread->getNbChannels(); if (nbOriginalChannels == 1) // SI mode => just stop and delete the thread @@ -500,8 +508,6 @@ void BladeRF2Input::stop() qDebug("BladeRF2Input::stop: MI mode. Not changing MI configuration. Just remove FIFO reference"); bladerf2InputThread->setFifo(requestedChannel, 0); // remove FIFO } - - m_running = false; } QByteArray BladeRF2Input::serialize() const diff --git a/plugins/samplesource/fcdpro/fcdproinput.cpp b/plugins/samplesource/fcdpro/fcdproinput.cpp index 6d4e9ca639..bb9ed3aa82 100644 --- a/plugins/samplesource/fcdpro/fcdproinput.cpp +++ b/plugins/samplesource/fcdpro/fcdproinput.cpp @@ -121,15 +121,18 @@ void FCDProInput::init() bool FCDProInput::start() { - qDebug() << "FCDProInput::start"; -// QMutexLocker mutexLocker(&m_mutex); + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_dev) { return false; } - if (m_running) stop(); + qDebug() << "FCDProInput::start"; /* Apply settings before streaming to avoid bus contention; * there is very little spare bandwidth on a full speed USB device. @@ -149,12 +152,12 @@ bool FCDProInput::start() m_FCDThread->setFcPos(m_settings.m_fcPos); m_FCDThread->setIQOrder(m_settings.m_iqOrder); m_FCDThread->startWork(); + m_running = true; -// mutexLocker.unlock(); + mutexLocker.unlock(); applySettings(m_settings, QList(), true); qDebug("FCDProInput::started"); - m_running = true; return true; } @@ -204,7 +207,13 @@ void FCDProInput::closeFCDAudio() void FCDProInput::stop() { -// QMutexLocker mutexLocker(&m_mutex); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + + m_running = false; if (m_FCDThread) { @@ -213,8 +222,6 @@ void FCDProInput::stop() delete m_FCDThread; m_FCDThread = nullptr; } - - m_running = false; } QByteArray FCDProInput::serialize() const diff --git a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp index 7ab4119b25..358ef76202 100644 --- a/plugins/samplesource/fcdproplus/fcdproplusinput.cpp +++ b/plugins/samplesource/fcdproplus/fcdproplusinput.cpp @@ -121,14 +121,14 @@ void FCDProPlusInput::init() bool FCDProPlusInput::start() { -// QMutexLocker mutexLocker(&m_mutex); + QMutexLocker mutexLocker(&m_mutex); if (!m_dev) { return false; } if (m_running) { - stop(); + return true; } qDebug() << "FCDProPlusInput::start"; @@ -151,12 +151,12 @@ bool FCDProPlusInput::start() m_FCDThread->setFcPos(m_settings.m_fcPos); m_FCDThread->setIQOrder(m_settings.m_iqOrder); m_FCDThread->startWork(); + m_running = true; -// mutexLocker.unlock(); + mutexLocker.unlock(); applySettings(m_settings, QList(), true); qDebug("FCDProPlusInput::started"); - m_running = true; return true; } @@ -170,7 +170,7 @@ void FCDProPlusInput::closeDevice() fcdClose(m_dev); m_dev = 0; - closeFCDAudio(); + closeFCDAudio(); } bool FCDProPlusInput::openFCDAudio(const char* cardname) @@ -208,6 +208,12 @@ void FCDProPlusInput::stop() { QMutexLocker mutexLocker(&m_mutex); + if (!m_running) { + return; + } + + m_running = false; + if (m_FCDThread) { m_FCDThread->stopWork(); @@ -215,8 +221,6 @@ void FCDProPlusInput::stop() delete m_FCDThread; m_FCDThread = nullptr; } - - m_running = false; } QByteArray FCDProPlusInput::serialize() const diff --git a/plugins/samplesource/hackrfinput/hackrfinput.cpp b/plugins/samplesource/hackrfinput/hackrfinput.cpp index 19321afc28..9b1ee95aa2 100644 --- a/plugins/samplesource/hackrfinput/hackrfinput.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinput.cpp @@ -142,29 +142,29 @@ void HackRFInput::init() bool HackRFInput::start() { -// QMutexLocker mutexLocker(&m_mutex); - if (!m_dev) { - return false; - } + QMutexLocker mutexLocker(&m_mutex); if (m_running) { - stop(); + return true; } - m_hackRFThread = new HackRFInputThread(m_dev, &m_sampleFifo); - -// mutexLocker.unlock(); + if (!m_dev) { + return false; + } - applySettings(m_settings, QList(), true); + m_hackRFThread = new HackRFInputThread(m_dev, &m_sampleFifo); m_hackRFThread->setSamplerate(m_settings.m_devSampleRate); m_hackRFThread->setLog2Decimation(m_settings.m_log2Decim); m_hackRFThread->setFcPos((int) m_settings.m_fcPos); m_hackRFThread->setIQOrder(m_settings.m_iqOrder); m_hackRFThread->startWork(); + m_running = true; + + mutexLocker.unlock(); + applySettings(m_settings, QList(), true); qDebug("HackRFInput::startInput: started"); - m_running = true; return true; } @@ -188,8 +188,14 @@ void HackRFInput::closeDevice() void HackRFInput::stop() { + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + qDebug("HackRFInput::stop"); -// QMutexLocker mutexLocker(&m_mutex); + m_running = false; if (m_hackRFThread) { @@ -197,8 +203,6 @@ void HackRFInput::stop() delete m_hackRFThread; m_hackRFThread = nullptr; } - - m_running = false; } QByteArray HackRFInput::serialize() const @@ -349,7 +353,7 @@ void HackRFInput::setDeviceCenterFrequency(quint64 freq_hz, int loPpmTenths) bool HackRFInput::applySettings(const HackRFInputSettings& settings, const QList& settingsKeys, bool force) { -// QMutexLocker mutexLocker(&m_mutex); + QMutexLocker mutexLocker(&m_mutex); qDebug() << "HackRFInput::applySettings: forcE: " << force << settings.getDebugString(settingsKeys, force); bool forwardChange = false; hackrf_error rc; diff --git a/plugins/samplesource/hackrfinput/hackrfinput.h b/plugins/samplesource/hackrfinput/hackrfinput.h index a13ec3eb18..0ac97587f1 100644 --- a/plugins/samplesource/hackrfinput/hackrfinput.h +++ b/plugins/samplesource/hackrfinput/hackrfinput.h @@ -153,7 +153,7 @@ class HackRFInput : public DeviceSampleSource { private: DeviceAPI *m_deviceAPI; - QMutex m_mutex; + QRecursiveMutex m_mutex; HackRFInputSettings m_settings; struct hackrf_device* m_dev; HackRFInputThread* m_hackRFThread; diff --git a/plugins/samplesource/limesdrinput/limesdrinput.cpp b/plugins/samplesource/limesdrinput/limesdrinput.cpp index d151872703..62d1a6efcb 100644 --- a/plugins/samplesource/limesdrinput/limesdrinput.cpp +++ b/plugins/samplesource/limesdrinput/limesdrinput.cpp @@ -409,14 +409,17 @@ void LimeSDRInput::init() bool LimeSDRInput::start() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } + if (!m_deviceShared.m_deviceParams->getDevice()) { return false; } - if (m_running) { stop(); } - - if (!acquireChannel()) - { + if (!acquireChannel()) { return false; } @@ -425,21 +428,28 @@ bool LimeSDRInput::start() m_limeSDRInputThread = new LimeSDRInputThread(&m_streamId, &m_sampleFifo, &m_replayBuffer); qDebug("LimeSDRInput::start: thread created"); - applySettings(m_settings, QList(), true); - m_limeSDRInputThread->setLog2Decimation(m_settings.m_log2SoftDecim); m_limeSDRInputThread->setIQOrder(m_settings.m_iqOrder); m_limeSDRInputThread->startWork(); - m_deviceShared.m_thread = m_limeSDRInputThread; m_running = true; + mutexLocker.unlock(); + applySettings(m_settings, QList(), true); + return true; } void LimeSDRInput::stop() { + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + qDebug("LimeSDRInput::stop"); + m_running = false; if (m_limeSDRInputThread) { @@ -449,7 +459,6 @@ void LimeSDRInput::stop() } m_deviceShared.m_thread = 0; - m_running = false; releaseChannel(); } @@ -803,7 +812,7 @@ bool LimeSDRInput::applySettings(const LimeSDRInputSettings& settings, const QLi bool doLPCalibration = false; double clockGenFreq = 0.0; -// QMutexLocker mutexLocker(&m_mutex); + QMutexLocker mutexLocker(&m_mutex); qint64 deviceCenterFrequency = settings.m_centerFrequency; deviceCenterFrequency -= settings.m_transverterMode ? settings.m_transverterDeltaFrequency : 0; diff --git a/plugins/samplesource/limesdrinput/limesdrinput.h b/plugins/samplesource/limesdrinput/limesdrinput.h index d86128e48e..a21c69de15 100644 --- a/plugins/samplesource/limesdrinput/limesdrinput.h +++ b/plugins/samplesource/limesdrinput/limesdrinput.h @@ -290,7 +290,7 @@ class LimeSDRInput : public DeviceSampleSource private: DeviceAPI *m_deviceAPI; - QMutex m_mutex; + QRecursiveMutex m_mutex; LimeSDRInputSettings m_settings; LimeSDRInputThread* m_limeSDRInputThread; QString m_deviceDescription; diff --git a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp index ac2f6051be..71a82ae0e2 100644 --- a/plugins/samplesource/plutosdrinput/plutosdrinput.cpp +++ b/plugins/samplesource/plutosdrinput/plutosdrinput.cpp @@ -102,35 +102,45 @@ void PlutoSDRInput::init() bool PlutoSDRInput::start() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } + if (!m_deviceShared.m_deviceParams->getBox()) { qCritical("PlutoSDRInput::start: device not open"); return false; } - if (m_running) { - stop(); - } - // start / stop streaming is done in the thread. m_plutoSDRInputThread = new PlutoSDRInputThread(PLUTOSDR_BLOCKSIZE_SAMPLES, m_deviceShared.m_deviceParams->getBox(), &m_sampleFifo); qDebug("PlutoSDRInput::start: thread created"); - applySettings(m_settings, QList(), true); - m_plutoSDRInputThread->setLog2Decimation(m_settings.m_log2Decim); m_plutoSDRInputThread->setIQOrder(m_settings.m_iqOrder); m_plutoSDRInputThread->startWork(); - m_deviceShared.m_thread = m_plutoSDRInputThread; m_running = true; + mutexLocker.unlock(); + applySettings(m_settings, QList(), true); + return true; } void PlutoSDRInput::stop() { + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + + m_running = false; + if (m_plutoSDRInputThread) { m_plutoSDRInputThread->stopWork(); @@ -139,7 +149,6 @@ void PlutoSDRInput::stop() } m_deviceShared.m_thread = nullptr; - m_running = false; } QByteArray PlutoSDRInput::serialize() const diff --git a/plugins/samplesource/sdrplay/sdrplayinput.cpp b/plugins/samplesource/sdrplay/sdrplayinput.cpp index e2e25d2361..8fe7049361 100644 --- a/plugins/samplesource/sdrplay/sdrplayinput.cpp +++ b/plugins/samplesource/sdrplay/sdrplayinput.cpp @@ -149,15 +149,17 @@ bool SDRPlayInput::openDevice() bool SDRPlayInput::start() { -// QMutexLocker mutexLocker(&m_mutex); - int res; + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_dev) { return false; } - if (m_running) stop(); - + int res; char s12FormatString[] = "336_S16"; if ((res = mirisdr_set_sample_format(m_dev, s12FormatString))) // sample format S12 @@ -197,11 +199,10 @@ bool SDRPlayInput::start() m_sdrPlayThread->setFcPos((int) m_settings.m_fcPos); m_sdrPlayThread->setIQOrder(m_settings.m_iqOrder); m_sdrPlayThread->startWork(); + m_running = true; -// mutexLocker.unlock(); - + mutexLocker.unlock(); applySettings(m_settings, QList(), true, true); - m_running = true; return true; } @@ -224,7 +225,13 @@ void SDRPlayInput::init() void SDRPlayInput::stop() { -// QMutexLocker mutexLocker(&m_mutex); + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + + m_running = false; if(m_sdrPlayThread) { @@ -232,8 +239,6 @@ void SDRPlayInput::stop() delete m_sdrPlayThread; m_sdrPlayThread = nullptr; } - - m_running = false; } QByteArray SDRPlayInput::serialize() const diff --git a/plugins/samplesource/sdrplay/sdrplayinput.h b/plugins/samplesource/sdrplay/sdrplayinput.h index dd3bae13e6..26be4d9b02 100644 --- a/plugins/samplesource/sdrplay/sdrplayinput.h +++ b/plugins/samplesource/sdrplay/sdrplayinput.h @@ -173,7 +173,7 @@ class SDRPlayInput : public DeviceSampleSource { private: DeviceAPI *m_deviceAPI; - QMutex m_mutex; + QRecursiveMutex m_mutex; SDRPlayVariant m_variant; SDRPlaySettings m_settings; mirisdr_dev_t* m_dev; diff --git a/plugins/samplesource/sdrplayv3/sdrplayv3input.cpp b/plugins/samplesource/sdrplayv3/sdrplayv3input.cpp index 5e25b0f688..2c64d457fb 100644 --- a/plugins/samplesource/sdrplayv3/sdrplayv3input.cpp +++ b/plugins/samplesource/sdrplayv3/sdrplayv3input.cpp @@ -147,20 +147,25 @@ bool SDRPlayV3Input::openDevice() bool SDRPlayV3Input::start() { - qDebug() << "SDRPlayV3Input::start"; + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_dev) { return false; } - if (m_running) stop(); + qDebug() << "SDRPlayV3Input::start"; m_sdrPlayThread = new SDRPlayV3Thread(m_dev, &m_sampleFifo, &m_replayBuffer); m_sdrPlayThread->setLog2Decimation(m_settings.m_log2Decim); m_sdrPlayThread->setFcPos((int) m_settings.m_fcPos); m_sdrPlayThread->startWork(); - m_running = m_sdrPlayThread->isRunning(); + + mutexLocker.unlock(); applySettings(m_settings, QList(), true, true); return true; @@ -184,17 +189,21 @@ void SDRPlayV3Input::init() void SDRPlayV3Input::stop() { - qDebug() << "SDRPlayV3Input::stop"; QMutexLocker mutexLocker(&m_mutex); + if (!m_running) { + return; + } + + qDebug() << "SDRPlayV3Input::stop"; + m_running = false; + if(m_sdrPlayThread) { m_sdrPlayThread->stopWork(); delete m_sdrPlayThread; m_sdrPlayThread = nullptr; } - - m_running = false; } QByteArray SDRPlayV3Input::serialize() const diff --git a/plugins/samplesource/sdrplayv3/sdrplayv3input.h b/plugins/samplesource/sdrplayv3/sdrplayv3input.h index 743e82d896..2b5e28f653 100644 --- a/plugins/samplesource/sdrplayv3/sdrplayv3input.h +++ b/plugins/samplesource/sdrplayv3/sdrplayv3input.h @@ -158,7 +158,7 @@ class SDRPlayV3Input : public DeviceSampleSource { private: DeviceAPI *m_deviceAPI; - QMutex m_mutex; + QRecursiveMutex m_mutex; SDRPlayV3Settings m_settings; sdrplay_api_DeviceT m_devs[SDRPLAY_MAX_DEVICES]; sdrplay_api_DeviceT* m_dev; diff --git a/plugins/samplesource/sigmffileinput/sigmffileinput.cpp b/plugins/samplesource/sigmffileinput/sigmffileinput.cpp index eaa852b74b..aade8c16ae 100644 --- a/plugins/samplesource/sigmffileinput/sigmffileinput.cpp +++ b/plugins/samplesource/sigmffileinput/sigmffileinput.cpp @@ -61,6 +61,7 @@ MESSAGE_CLASS_DEFINITION(SigMFFileInput::MsgReportTotalSamplesCheck, Message) SigMFFileInput::SigMFFileInput(DeviceAPI *deviceAPI) : m_deviceAPI(deviceAPI), + m_running(false), m_settings(), m_trackMode(false), m_currentTrackIndex(0), @@ -446,13 +447,18 @@ void SigMFFileInput::init() bool SigMFFileInput::start() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } + if (!m_dataStream.is_open()) { qWarning("SigMFFileInput::start: file not open. not starting"); return false; } - QMutexLocker mutexLocker(&m_mutex); qDebug() << "SigMFFileInput::start"; if (m_dataStream.tellg() != (std::streampos) 0) { @@ -472,6 +478,7 @@ bool SigMFFileInput::start() m_fileInputWorker->setTrackIndex(0); m_fileInputWorker->moveToThread(&m_fileInputWorkerThread); m_deviceDescription = "SigMFFileInput"; + m_running = true; mutexLocker.unlock(); qDebug("SigMFFileInput::startInput: started"); @@ -486,9 +493,15 @@ bool SigMFFileInput::start() void SigMFFileInput::stop() { - qDebug() << "SigMFFileInput::stop"; QMutexLocker mutexLocker(&m_mutex); + if (!m_running) { + return; + } + + qDebug() << "SigMFFileInput::stop"; + m_running = false; + if (m_fileInputWorker) { stopWorker(); diff --git a/plugins/samplesource/sigmffileinput/sigmffileinput.h b/plugins/samplesource/sigmffileinput/sigmffileinput.h index 3705ff9b8a..f612b31bfe 100644 --- a/plugins/samplesource/sigmffileinput/sigmffileinput.h +++ b/plugins/samplesource/sigmffileinput/sigmffileinput.h @@ -446,6 +446,7 @@ class SigMFFileInput : public DeviceSampleSource { private: DeviceAPI *m_deviceAPI; QMutex m_mutex; + bool m_running; SigMFFileInputSettings m_settings; std::ifstream m_metaStream; std::ifstream m_dataStream; diff --git a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp index a7b5b9ddbe..f7280fd938 100644 --- a/plugins/samplesource/soapysdrinput/soapysdrinput.cpp +++ b/plugins/samplesource/soapysdrinput/soapysdrinput.cpp @@ -481,6 +481,11 @@ bool SoapySDRInput::start() // // Note: this is quite similar to the BladeRF2 start handling. The main difference is that the channel allocation (enabling) process is // done in the thread object. + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_openSuccess) { @@ -595,11 +600,13 @@ void SoapySDRInput::stop() // // Note: this is quite similar to the BladeRF2 stop handling. The main difference is that the channel allocation (enabling) process is // done in the thread object. + QMutexLocker mutexLocker(&m_mutex); if (!m_running) { return; } + m_running = false; int requestedChannel = m_deviceAPI->getDeviceItemIndex(); SoapySDRInputThread *soapySDRInputThread = findThread(); @@ -688,8 +695,6 @@ void SoapySDRInput::stop() qDebug("SoapySDRInput::stop: MI mode. Not changing MI configuration. Just remove FIFO reference"); soapySDRInputThread->setFifo(requestedChannel, nullptr); // remove FIFO } - - m_running = false; } QByteArray SoapySDRInput::serialize() const diff --git a/plugins/samplesource/testsource/testsourceinput.cpp b/plugins/samplesource/testsource/testsourceinput.cpp index 350a49f5fa..9e79c74464 100644 --- a/plugins/samplesource/testsource/testsourceinput.cpp +++ b/plugins/samplesource/testsource/testsourceinput.cpp @@ -119,11 +119,16 @@ bool TestSourceInput::start() void TestSourceInput::stop() { QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + m_running = false; if (m_testSourceWorkerThread) { - m_testSourceWorker->stopWork(); + m_testSourceWorker->stopWork(); m_testSourceWorkerThread->quit(); m_testSourceWorkerThread->wait(); m_testSourceWorker = nullptr; diff --git a/plugins/samplesource/usrpinput/usrpinput.cpp b/plugins/samplesource/usrpinput/usrpinput.cpp index e317aa5b8d..b6d8eb1c7c 100644 --- a/plugins/samplesource/usrpinput/usrpinput.cpp +++ b/plugins/samplesource/usrpinput/usrpinput.cpp @@ -414,14 +414,17 @@ void USRPInput::init() bool USRPInput::start() { + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } + if (!m_deviceShared.m_deviceParams->getDevice()) { return false; } - if (m_running) { stop(); } - - if (!acquireChannel()) - { + if (!acquireChannel()) { return false; } @@ -441,7 +444,14 @@ bool USRPInput::start() void USRPInput::stop() { + QMutexLocker mutexLocker(&m_mutex); + + if (!m_running) { + return; + } + qDebug("USRPInput::stop"); + m_running = false; if (m_usrpInputThread) { @@ -451,7 +461,6 @@ void USRPInput::stop() } m_deviceShared.m_thread = 0; - m_running = false; releaseChannel(); } diff --git a/plugins/samplesource/xtrxinput/xtrxinput.cpp b/plugins/samplesource/xtrxinput/xtrxinput.cpp index cf9f4ad70e..5aac520cad 100644 --- a/plugins/samplesource/xtrxinput/xtrxinput.cpp +++ b/plugins/samplesource/xtrxinput/xtrxinput.cpp @@ -275,6 +275,11 @@ bool XTRXInput::start() // // Eventually it registers the FIFO in the thread. If the thread has to be started it enables the channels up to the number of channels // allocated in the thread and starts the thread. + QMutexLocker mutexLocker(&m_mutex); + + if (m_running) { + return true; + } if (!m_deviceShared.m_dev || !m_deviceShared.m_dev->getDevice()) { @@ -353,8 +358,6 @@ bool XTRXInput::start() xtrxInputThread->setFifo(requestedChannel, &m_sampleFifo); xtrxInputThread->setLog2Decimation(requestedChannel, m_settings.m_log2SoftDecim); - applySettings(m_settings, QList(), true); - if (needsStart) { qDebug("XTRXInput::start: (re)start thread"); @@ -364,6 +367,9 @@ bool XTRXInput::start() qDebug("XTRXInput::start: started"); m_running = true; + m_mutex.unlock(); + applySettings(m_settings, QList(), true); + return true; } @@ -377,11 +383,13 @@ void XTRXInput::stop() // If the thread is currently managing both channels (MI mode) then we are removing one channel. Thus we must // transition from MI to SI. This transition is handled by stopping the thread, deleting it and creating a new one // managing a single channel. + QMutexLocker mutexLocker(&m_mutex); if (!m_running) { return; } + m_running = false; int removedChannel = m_deviceAPI->getDeviceItemIndex(); // channel to remove int requestedChannel = removedChannel ^ 1; // channel to keep (opposite channel) XTRXInputThread *xtrxInputThread = findThread(); @@ -432,8 +440,6 @@ void XTRXInput::stop() applySettings(m_settings, QList(), true); xtrxInputThread->startWork(); } - - m_running = false; } void XTRXInput::suspendTxThread()