From e8537d65822adb154a011eeae3547041bbd3a69f Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 14 Feb 2018 11:27:57 +0100 Subject: [PATCH] Web API and related: fixed memory leaks and some malfunctions --- .../filesource/filesourceinput.cpp | 32 ++++++++----------- plugins/samplesource/perseus/perseusinput.cpp | 2 +- sdrbase/dsp/dspdevicesinkengine.cpp | 8 +++-- sdrbase/dsp/dspdevicesourceengine.cpp | 3 +- sdrgui/webapi/webapiadaptergui.cpp | 31 ++++++++++++++++-- sdrsrv/maincore.cpp | 6 ++++ sdrsrv/webapi/webapiadaptersrv.cpp | 21 ++++++++++++ 7 files changed, 79 insertions(+), 24 deletions(-) diff --git a/plugins/samplesource/filesource/filesourceinput.cpp b/plugins/samplesource/filesource/filesourceinput.cpp index 354a0ad65..3b8f39f11 100644 --- a/plugins/samplesource/filesource/filesourceinput.cpp +++ b/plugins/samplesource/filesource/filesourceinput.cpp @@ -98,13 +98,12 @@ void FileSourceInput::openFileStream() << " fileSize: " << fileSize << "bytes" << " length: " << m_recordLength << " seconds"; - MsgReportFileSourceStreamData *report = MsgReportFileSourceStreamData::create(m_sampleRate, - m_sampleSize, - m_centerFrequency, - m_startingTimeStamp, - m_recordLength); // file stream data - if (getMessageQueueToGUI()) { + MsgReportFileSourceStreamData *report = MsgReportFileSourceStreamData::create(m_sampleRate, + m_sampleSize, + m_centerFrequency, + m_startingTimeStamp, + m_recordLength); // file stream data getMessageQueueToGUI()->push(report); } } @@ -161,9 +160,8 @@ bool FileSourceInput::start() //applySettings(m_generalSettings, m_settings, true); qDebug("FileSourceInput::startInput: started"); - MsgReportFileSourceAcquisition *report = MsgReportFileSourceAcquisition::create(true); // acquisition on - if (getMessageQueueToGUI()) { + MsgReportFileSourceAcquisition *report = MsgReportFileSourceAcquisition::create(true); // acquisition on getMessageQueueToGUI()->push(report); } @@ -184,9 +182,8 @@ void FileSourceInput::stop() m_deviceDescription.clear(); - MsgReportFileSourceAcquisition *report = MsgReportFileSourceAcquisition::create(false); // acquisition off - if (getMessageQueueToGUI()) { + MsgReportFileSourceAcquisition *report = MsgReportFileSourceAcquisition::create(false); // acquisition off getMessageQueueToGUI()->push(report); } } @@ -209,10 +206,10 @@ bool FileSourceInput::deserialize(const QByteArray& data) MsgConfigureFileSource* message = MsgConfigureFileSource::create(m_settings); m_inputMessageQueue.push(message); - if (m_guiMessageQueue) + if (getMessageQueueToGUI()) { MsgConfigureFileSource* messageToGUI = MsgConfigureFileSource::create(m_settings); - m_guiMessageQueue->push(messageToGUI); + getMessageQueueToGUI()->push(messageToGUI); } return success; @@ -241,10 +238,10 @@ void FileSourceInput::setCenterFrequency(qint64 centerFrequency) MsgConfigureFileSource* message = MsgConfigureFileSource::create(m_settings); m_inputMessageQueue.push(message); - if (m_guiMessageQueue) + if (getMessageQueueToGUI()) { MsgConfigureFileSource* messageToGUI = MsgConfigureFileSource::create(m_settings); - m_guiMessageQueue->push(messageToGUI); + getMessageQueueToGUI()->push(messageToGUI); } } @@ -299,9 +296,8 @@ bool FileSourceInput::handleMessage(const Message& message) if (m_fileSourceThread != 0) { - report = MsgReportFileSourceStreamTiming::create(m_fileSourceThread->getSamplesCount()); - if (getMessageQueueToGUI()) { + report = MsgReportFileSourceStreamTiming::create(m_fileSourceThread->getSamplesCount()); getMessageQueueToGUI()->push(report); } } @@ -361,10 +357,10 @@ int FileSourceInput::webapiRun( MsgStartStop *message = MsgStartStop::create(run); m_inputMessageQueue.push(message); - if (m_guiMessageQueue) // forward to GUI if any + if (getMessageQueueToGUI()) // forward to GUI if any { MsgStartStop *msgToGUI = MsgStartStop::create(run); - m_guiMessageQueue->push(msgToGUI); + getMessageQueueToGUI()->push(msgToGUI); } return 200; diff --git a/plugins/samplesource/perseus/perseusinput.cpp b/plugins/samplesource/perseus/perseusinput.cpp index 4ee9380c2..2e4225f31 100644 --- a/plugins/samplesource/perseus/perseusinput.cpp +++ b/plugins/samplesource/perseus/perseusinput.cpp @@ -264,7 +264,7 @@ void PerseusInput::closeDevice() { if (m_perseusDescriptor) { - perseus_stop_async_input(m_perseusDescriptor); + if (m_running) { stop(); } perseus_close(m_perseusDescriptor); } } diff --git a/sdrbase/dsp/dspdevicesinkengine.cpp b/sdrbase/dsp/dspdevicesinkengine.cpp index 82d65701a..89d58fb89 100644 --- a/sdrbase/dsp/dspdevicesinkengine.cpp +++ b/sdrbase/dsp/dspdevicesinkengine.cpp @@ -48,6 +48,7 @@ DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) : DSPDeviceSinkEngine::~DSPDeviceSinkEngine() { + stop(); wait(); } @@ -70,8 +71,11 @@ void DSPDeviceSinkEngine::start() void DSPDeviceSinkEngine::stop() { qDebug() << "DSPDeviceSinkEngine::stop"; - DSPExit cmd; - m_syncMessenger.sendWait(cmd); + gotoIdle(); + m_state = StNotStarted; + QThread::exit(); +// DSPExit cmd; +// m_syncMessenger.sendWait(cmd); } bool DSPDeviceSinkEngine::initGeneration() diff --git a/sdrbase/dsp/dspdevicesourceengine.cpp b/sdrbase/dsp/dspdevicesourceengine.cpp index 176025e5d..6a64e5202 100644 --- a/sdrbase/dsp/dspdevicesourceengine.cpp +++ b/sdrbase/dsp/dspdevicesourceengine.cpp @@ -52,7 +52,8 @@ DSPDeviceSourceEngine::DSPDeviceSourceEngine(uint uid, QObject* parent) : DSPDeviceSourceEngine::~DSPDeviceSourceEngine() { - wait(); + stop(); + wait(); } void DSPDeviceSourceEngine::run() diff --git a/sdrgui/webapi/webapiadaptergui.cpp b/sdrgui/webapi/webapiadaptergui.cpp index 847851b6e..c43fd8c06 100644 --- a/sdrgui/webapi/webapiadaptergui.cpp +++ b/sdrgui/webapi/webapiadaptergui.cpp @@ -386,6 +386,7 @@ int WebAPIAdapterGUI::instancePresetsGet( } swgPresets->append(new SWGSDRangel::SWGPresetItem); + swgPresets->back()->init(); swgPresets->back()->setCenterFrequency(preset->getCenterFrequency()); *swgPresets->back()->getType() = preset->isSourcePreset() ? "R" : "T"; *swgPresets->back()->getName() = preset->getDescription(); @@ -409,6 +410,7 @@ int WebAPIAdapterGUI::instancePresetPatch( if (deviceSetIndex >= nbDeviceSets) { + error.init(); *error.getMessage() = QString("There is no device set at index %1. Number of device sets is %2").arg(deviceSetIndex).arg(nbDeviceSets); return 404; } @@ -419,6 +421,7 @@ int WebAPIAdapterGUI::instancePresetPatch( if (selectedPreset == 0) { + error.init(); *error.getMessage() = QString("There is no preset [%1, %2, %3]") .arg(*presetIdentifier->getGroupName()) .arg(presetIdentifier->getCenterFrequency()) @@ -430,12 +433,14 @@ int WebAPIAdapterGUI::instancePresetPatch( if (deviceUI->m_deviceSourceEngine && !selectedPreset->isSourcePreset()) { + error.init(); *error.getMessage() = QString("Preset type (T) and device set type (Rx) mismatch"); return 404; } if (deviceUI->m_deviceSinkEngine && selectedPreset->isSourcePreset()) { + error.init(); *error.getMessage() = QString("Preset type (R) and device set type (Tx) mismatch"); return 404; } @@ -463,6 +468,7 @@ int WebAPIAdapterGUI::instancePresetPut( if (deviceSetIndex >= nbDeviceSets) { + error.init(); *error.getMessage() = QString("There is no device set at index %1. Number of device sets is %2").arg(deviceSetIndex).arg(nbDeviceSets); return 404; } @@ -473,6 +479,7 @@ int WebAPIAdapterGUI::instancePresetPut( if (selectedPreset == 0) { + error.init(); *error.getMessage() = QString("There is no preset [%1, %2, %3]") .arg(*presetIdentifier->getGroupName()) .arg(presetIdentifier->getCenterFrequency()) @@ -485,12 +492,14 @@ int WebAPIAdapterGUI::instancePresetPut( if (deviceUI->m_deviceSourceEngine && !selectedPreset->isSourcePreset()) { + error.init(); *error.getMessage() = QString("Preset type (T) and device set type (Rx) mismatch"); return 404; } if (deviceUI->m_deviceSinkEngine && selectedPreset->isSourcePreset()) { + error.init(); *error.getMessage() = QString("Preset type (R) and device set type (Tx) mismatch"); return 404; } @@ -519,12 +528,26 @@ int WebAPIAdapterGUI::instancePresetPost( if (deviceSetIndex >= nbDeviceSets) { + error.init(); *error.getMessage() = QString("There is no device set at index %1. Number of device sets is %2").arg(deviceSetIndex).arg(nbDeviceSets); return 404; } + DeviceUISet *deviceSet = m_mainWindow.m_deviceUIs[deviceSetIndex]; + int deviceCenterFrequency = 0; + + if (deviceSet->m_deviceSourceEngine) { // Rx + deviceCenterFrequency = deviceSet->m_deviceSourceEngine->getSource()->getCenterFrequency(); + } else if (deviceSet->m_deviceSinkEngine) { // Tx + deviceCenterFrequency = deviceSet->m_deviceSinkEngine->getSink()->getCenterFrequency(); + } else { + error.init(); + *error.getMessage() = QString("Device set error"); + return 500; + } + const Preset *selectedPreset = m_mainWindow.m_settings.getPreset(*presetIdentifier->getGroupName(), - presetIdentifier->getCenterFrequency(), + deviceCenterFrequency, *presetIdentifier->getName()); if (selectedPreset == 0) // save on a new preset @@ -533,9 +556,10 @@ int WebAPIAdapterGUI::instancePresetPost( } else { + error.init(); *error.getMessage() = QString("Preset already exists [%1, %2, %3]") .arg(*presetIdentifier->getGroupName()) - .arg(presetIdentifier->getCenterFrequency()) + .arg(deviceCenterFrequency) .arg(*presetIdentifier->getName()); return 409; } @@ -1287,6 +1311,7 @@ void WebAPIAdapterGUI::getDeviceSetList(SWGSDRangel::SWGDeviceSetList* deviceSet void WebAPIAdapterGUI::getDeviceSet(SWGSDRangel::SWGDeviceSet *deviceSet, const DeviceUISet* deviceUISet, int deviceUISetIndex) { + deviceSet->init(); SWGSDRangel::SWGSamplingDevice *samplingDevice = deviceSet->getSamplingDevice(); samplingDevice->init(); samplingDevice->setIndex(deviceUISetIndex); @@ -1313,6 +1338,7 @@ void WebAPIAdapterGUI::getDeviceSet(SWGSDRangel::SWGDeviceSet *deviceSet, const for (int i = 0; i < deviceSet->getChannelcount(); i++) { channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); ChannelSourceAPI *channel = deviceUISet->m_deviceSinkAPI->getChanelAPIAt(i); channels->back()->setDeltaFrequency(channel->getCenterFrequency()); channels->back()->setIndex(channel->getIndexInDeviceSet()); @@ -1343,6 +1369,7 @@ void WebAPIAdapterGUI::getDeviceSet(SWGSDRangel::SWGDeviceSet *deviceSet, const for (int i = 0; i < deviceSet->getChannelcount(); i++) { channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); ChannelSinkAPI *channel = deviceUISet->m_deviceSourceAPI->getChanelAPIAt(i); channels->back()->setDeltaFrequency(channel->getCenterFrequency()); channels->back()->setIndex(channel->getIndexInDeviceSet()); diff --git a/sdrsrv/maincore.cpp b/sdrsrv/maincore.cpp index bae083d60..60f086631 100644 --- a/sdrsrv/maincore.cpp +++ b/sdrsrv/maincore.cpp @@ -79,6 +79,10 @@ MainCore::MainCore(qtwebapp::LoggerWithFile *logger, const MainParser& parser, Q MainCore::~MainCore() { + while (m_deviceSets.size() > 0) { + removeLastDevice(); + } + m_apiServer->stop(); m_settings.save(); delete m_apiServer; @@ -338,6 +342,7 @@ void MainCore::removeLastDevice() m_deviceSets.back()->m_deviceSourceAPI->getPluginInterface()->deleteSampleSourcePluginInstanceInput( m_deviceSets.back()->m_deviceSourceAPI->getSampleSource()); m_deviceSets.back()->m_deviceSourceAPI->clearBuddiesLists(); // clear old API buddies lists + delete m_deviceSets.back()->m_deviceSourceAPI; delete m_deviceSets.back(); @@ -355,6 +360,7 @@ void MainCore::removeLastDevice() m_deviceSets.back()->m_deviceSinkAPI->getPluginInterface()->deleteSampleSinkPluginInstanceOutput( m_deviceSets.back()->m_deviceSinkAPI->getSampleSink()); m_deviceSets.back()->m_deviceSinkAPI->clearBuddiesLists(); // clear old API buddies lists + delete m_deviceSets.back()->m_deviceSinkAPI; delete m_deviceSets.back(); diff --git a/sdrsrv/webapi/webapiadaptersrv.cpp b/sdrsrv/webapi/webapiadaptersrv.cpp index 76cfa6700..62efda069 100644 --- a/sdrsrv/webapi/webapiadaptersrv.cpp +++ b/sdrsrv/webapi/webapiadaptersrv.cpp @@ -393,12 +393,14 @@ int WebAPIAdapterSrv::instancePresetFilePut( } else { + error.init(); *error.getMessage() = QString("File %1 not found or not readable").arg(fileName); return 404; } } else { + error.init(); *error.getMessage() = QString("Empty file path"); return 404; } @@ -418,6 +420,7 @@ int WebAPIAdapterSrv::instancePresetFilePost( if (selectedPreset == 0) { + error.init(); *error.getMessage() = QString("There is no preset [%1, %2, %3]") .arg(*presetIdentifier->getGroupName()) .arg(presetIdentifier->getCenterFrequency()) @@ -453,12 +456,14 @@ int WebAPIAdapterSrv::instancePresetFilePost( } else { + error.init(); *error.getMessage() = QString("File %1 cannot be written").arg(filePath); return 404; } } else { + error.init(); *error.getMessage() = QString("Empty file path"); return 404; } @@ -496,6 +501,7 @@ int WebAPIAdapterSrv::instancePresetsGet( } swgPresets->append(new SWGSDRangel::SWGPresetItem); + swgPresets->back()->init(); swgPresets->back()->setCenterFrequency(preset->getCenterFrequency()); *swgPresets->back()->getType() = preset->isSourcePreset() ? "R" : "T"; *swgPresets->back()->getName() = preset->getDescription(); @@ -519,6 +525,7 @@ int WebAPIAdapterSrv::instancePresetPatch( if (deviceSetIndex >= nbDeviceSets) { + error.init(); *error.getMessage() = QString("There is no device set at index %1. Number of device sets is %2").arg(deviceSetIndex).arg(nbDeviceSets); return 404; } @@ -529,6 +536,7 @@ int WebAPIAdapterSrv::instancePresetPatch( if (selectedPreset == 0) { + error.init(); *error.getMessage() = QString("There is no preset [%1, %2, %3]") .arg(*presetIdentifier->getGroupName()) .arg(presetIdentifier->getCenterFrequency()) @@ -540,12 +548,14 @@ int WebAPIAdapterSrv::instancePresetPatch( if (deviceSet->m_deviceSourceEngine && !selectedPreset->isSourcePreset()) { + error.init(); *error.getMessage() = QString("Preset type (T) and device set type (Rx) mismatch"); return 404; } if (deviceSet->m_deviceSinkEngine && selectedPreset->isSourcePreset()) { + error.init(); *error.getMessage() = QString("Preset type (R) and device set type (Tx) mismatch"); return 404; } @@ -573,6 +583,7 @@ int WebAPIAdapterSrv::instancePresetPut( if (deviceSetIndex >= nbDeviceSets) { + error.init(); *error.getMessage() = QString("There is no device set at index %1. Number of device sets is %2").arg(deviceSetIndex).arg(nbDeviceSets); return 404; } @@ -583,6 +594,7 @@ int WebAPIAdapterSrv::instancePresetPut( if (selectedPreset == 0) { + error.init(); *error.getMessage() = QString("There is no preset [%1, %2, %3]") .arg(*presetIdentifier->getGroupName()) .arg(presetIdentifier->getCenterFrequency()) @@ -595,12 +607,14 @@ int WebAPIAdapterSrv::instancePresetPut( if (deviceSet->m_deviceSourceEngine && !selectedPreset->isSourcePreset()) { + error.init(); *error.getMessage() = QString("Preset type (T) and device set type (Rx) mismatch"); return 404; } if (deviceSet->m_deviceSinkEngine && selectedPreset->isSourcePreset()) { + error.init(); *error.getMessage() = QString("Preset type (R) and device set type (Tx) mismatch"); return 404; } @@ -629,6 +643,7 @@ int WebAPIAdapterSrv::instancePresetPost( if (deviceSetIndex >= nbDeviceSets) { + error.init(); *error.getMessage() = QString("There is no device set at index %1. Number of device sets is %2").arg(deviceSetIndex).arg(nbDeviceSets); return 404; } @@ -641,6 +656,7 @@ int WebAPIAdapterSrv::instancePresetPost( } else if (deviceSet->m_deviceSinkEngine) { // Tx deviceCenterFrequency = deviceSet->m_deviceSinkEngine->getSink()->getCenterFrequency(); } else { + error.init(); *error.getMessage() = QString("Device set error"); return 500; } @@ -655,6 +671,7 @@ int WebAPIAdapterSrv::instancePresetPost( } else { + error.init(); *error.getMessage() = QString("Preset already exists [%1, %2, %3]") .arg(*presetIdentifier->getGroupName()) .arg(deviceCenterFrequency) @@ -684,6 +701,7 @@ int WebAPIAdapterSrv::instancePresetDelete( if (selectedPreset == 0) { + error.init(); *error.getMessage() = QString("There is no preset [%1, %2, %3]") .arg(*response.getGroupName()) .arg(response.getCenterFrequency()) @@ -1388,6 +1406,7 @@ void WebAPIAdapterSrv::getDeviceSetList(SWGSDRangel::SWGDeviceSetList* deviceSet void WebAPIAdapterSrv::getDeviceSet(SWGSDRangel::SWGDeviceSet *swgDeviceSet, const DeviceSet* deviceSet, int deviceUISetIndex) { + swgDeviceSet->init(); SWGSDRangel::SWGSamplingDevice *samplingDevice = swgDeviceSet->getSamplingDevice(); samplingDevice->init(); samplingDevice->setIndex(deviceUISetIndex); @@ -1414,6 +1433,7 @@ void WebAPIAdapterSrv::getDeviceSet(SWGSDRangel::SWGDeviceSet *swgDeviceSet, con for (int i = 0; i < swgDeviceSet->getChannelcount(); i++) { channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); ChannelSourceAPI *channel = deviceSet->m_deviceSinkAPI->getChanelAPIAt(i); channels->back()->setDeltaFrequency(channel->getCenterFrequency()); channels->back()->setIndex(channel->getIndexInDeviceSet()); @@ -1444,6 +1464,7 @@ void WebAPIAdapterSrv::getDeviceSet(SWGSDRangel::SWGDeviceSet *swgDeviceSet, con for (int i = 0; i < swgDeviceSet->getChannelcount(); i++) { channels->append(new SWGSDRangel::SWGChannel); + channels->back()->init(); ChannelSinkAPI *channel = deviceSet->m_deviceSourceAPI->getChanelAPIAt(i); channels->back()->setDeltaFrequency(channel->getCenterFrequency()); channels->back()->setIndex(channel->getIndexInDeviceSet());