From 5ace021e41e950387dee0adc9797705b537a8b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Tue, 1 Nov 2022 01:12:04 +0100 Subject: [PATCH] added mutexes --- .../Calibration/amplitudecaldialog.cpp | 8 ++-- .../LibreVNA-GUI/Calibration/calibration.cpp | 12 ++++++ .../LibreVNA-GUI/Calibration/calibration.h | 2 + .../Calibration/frequencycaldialog.cpp | 2 +- .../LibreVNA-GUI/Device/device.cpp | 22 +++++++---- .../LibreVNA-GUI/Device/device.h | 2 + .../LibreVNA-GUI/Device/deviceusblog.cpp | 39 ++++++++++++++++++- .../LibreVNA-GUI/Device/deviceusblog.h | 13 ++++++- .../LibreVNA-GUI/Device/deviceusblogview.cpp | 13 ++++++- .../LibreVNA-GUI/Device/deviceusblogview.ui | 7 ++++ .../Device/firmwareupdatedialog.cpp | 4 +- .../Device/manualcontroldialog.cpp | 2 +- .../LibreVNA-GUI/Traces/traceplot.cpp | 1 + .../PC_Application/LibreVNA-GUI/appwindow.cpp | 6 ++- 14 files changed, 112 insertions(+), 21 deletions(-) diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/amplitudecaldialog.cpp b/Software/PC_Application/LibreVNA-GUI/Calibration/amplitudecaldialog.cpp index 4714bd7..418dca7 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/amplitudecaldialog.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/amplitudecaldialog.cpp @@ -134,7 +134,7 @@ AmplitudeCalDialog::AmplitudeCalDialog(Device *dev, ModeHandler *handler, QWidge }); connect(ui->automatic, &QPushButton::clicked, this, &AmplitudeCalDialog::AutomaticMeasurementDialog); - connect(dev, &Device::SpectrumResultReceived, this, &AmplitudeCalDialog::ReceivedMeasurement); + connect(dev, &Device::SpectrumResultReceived, this, &AmplitudeCalDialog::ReceivedMeasurement, Qt::QueuedConnection); } AmplitudeCalDialog::~AmplitudeCalDialog() @@ -211,7 +211,7 @@ void AmplitudeCalDialog::LoadFromDevice() dev->SetIdle(); RemoveAllPoints(); // qDebug() << "Asking for amplitude calibration"; - connect(dev, &Device::AmplitudeCorrectionPointReceived, this, &AmplitudeCalDialog::ReceivedPoint); + connect(dev, &Device::AmplitudeCorrectionPointReceived, this, &AmplitudeCalDialog::ReceivedPoint, Qt::QueuedConnection); dev->SendCommandWithoutPayload(requestCommand()); edited = false; UpdateSaveButton(); @@ -401,7 +401,7 @@ void AmplitudeCalDialog::AutomaticMeasurementDialog() disconnect(dev, &Device::AmplitudeCorrectionPointReceived, this, nullptr); qDebug() << "Received" << p.totalPoints << "points for automatic calibration"; } - }); + }, Qt::QueuedConnection); // request points of otherCal // switch between source/receiver calibration auto request = automatic.isSourceCal ? Protocol::PacketType::RequestReceiverCal : Protocol::PacketType::RequestSourceCal; @@ -414,7 +414,7 @@ void AmplitudeCalDialog::AutomaticMeasurementDialog() AddPoint(p.frequency); } // intialize measurement state machine - connect(dev, &Device::SpectrumResultReceived, this, &AmplitudeCalDialog::ReceivedAutomaticMeasurementResult); + connect(dev, &Device::SpectrumResultReceived, this, &AmplitudeCalDialog::ReceivedAutomaticMeasurementResult, Qt::QueuedConnection); automatic.measuringPort2 = false; automatic.measuringCount = 0; ui->status->setText("Taking measurements..."); diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp index 76d8400..9a0687d 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.cpp @@ -315,6 +315,7 @@ Calibration::Type Calibration::TypeFromString(QString s) void Calibration::correctMeasurement(VirtualDevice::VNAMeasurement &d) { + lock_guard guard(access); if(caltype.type == Type::None) { // no calibration active, nothing to do return; @@ -422,6 +423,7 @@ void Calibration::edit() } auto updateCalStatistics = [=](){ + lock_guard guard(access); ui->activeCalibration->setText(caltype.getReadableDescription()); ui->calPoints->setValue(points.size()); if(points.size() > 0) { @@ -434,6 +436,7 @@ void Calibration::edit() }; auto updateCalButtons = [=](){ + lock_guard guard(access); auto row = ui->calibrationList->currentRow(); if(row < 0) { ui->activate->setEnabled(false); @@ -993,6 +996,7 @@ Calibration::CalType Calibration::getCaltype() const Calibration::InterpolationType Calibration::getInterpolation(double f_start, double f_stop, int npoints) { + lock_guard guard(access); if(!points.size()) { return InterpolationType::NoCalibration; } @@ -1026,6 +1030,7 @@ Calibration::InterpolationType Calibration::getInterpolation(double f_start, dou std::vector Calibration::getErrorTermTraces() { + lock_guard guard(access); vector ret; if(points.size() == 0) { return ret; @@ -1088,6 +1093,7 @@ std::vector Calibration::getErrorTermTraces() std::vector Calibration::getMeasurementTraces() { + lock_guard guard(access); vector ret; for(auto m : measurements) { switch(m->getType()) { @@ -1249,6 +1255,7 @@ Calkit &Calibration::getKit() nlohmann::json Calibration::toJSON() { + lock_guard guard(access); nlohmann::json j; j["format"] = 3; nlohmann::json jmeasurements; @@ -1276,6 +1283,7 @@ nlohmann::json Calibration::toJSON() void Calibration::fromJSON(nlohmann::json j) { reset(); + lock_guard guard(access); if(j.contains("calkit")) { kit.fromJSON(j["calkit"]); } @@ -1642,6 +1650,7 @@ bool Calibration::canCompute(Calibration::CalType type, double *startFreq, doubl bool Calibration::compute(Calibration::CalType type) { + lock_guard guard(access); if(type.type == Type::None) { deactivate(); return true; @@ -1719,6 +1728,7 @@ void Calibration::measurementsComplete() void Calibration::deactivate() { + lock_guard guard(access); points.clear(); caltype.type = Type::None; caltype.usedPorts.clear(); @@ -1740,6 +1750,7 @@ QString Calibration::DefaultMeasurementsToString(Calibration::DefaultMeasurement void Calibration::createDefaultMeasurements(Calibration::DefaultMeasurements dm) { + lock_guard guard(access); auto createSOL = [=](int port) { auto _short = new CalibrationMeasurement::Short(this); _short->setPort(port); @@ -1793,6 +1804,7 @@ void Calibration::createDefaultMeasurements(Calibration::DefaultMeasurements dm) void Calibration::deleteMeasurements() { + lock_guard guard(access); for(auto m : measurements) { delete m; } diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h index 7cbf83c..358366f 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/calibration.h @@ -155,6 +155,8 @@ private: QString currentCalFile; bool unsavedChanges; + + std::recursive_mutex access; }; #endif // CALIBRATION2_H diff --git a/Software/PC_Application/LibreVNA-GUI/Calibration/frequencycaldialog.cpp b/Software/PC_Application/LibreVNA-GUI/Calibration/frequencycaldialog.cpp index abd04f8..8f37a72 100644 --- a/Software/PC_Application/LibreVNA-GUI/Calibration/frequencycaldialog.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Calibration/frequencycaldialog.cpp @@ -13,7 +13,7 @@ FrequencyCalDialog::FrequencyCalDialog(Device *dev, ModeHandler *handler, QWidg ui->ppm->setPrecision(4); ui->ppm->setValue(0.0); - connect(dev, &Device::FrequencyCorrectionReceived, ui->ppm, &SIUnitEdit::setValueQuiet); + connect(dev, &Device::FrequencyCorrectionReceived, ui->ppm, &SIUnitEdit::setValueQuiet, Qt::QueuedConnection); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){ // get value and transfer to device diff --git a/Software/PC_Application/LibreVNA-GUI/Device/device.cpp b/Software/PC_Application/LibreVNA-GUI/Device/device.cpp index 329d962..e707c79 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/device.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/device.cpp @@ -453,6 +453,7 @@ const Protocol::DeviceInfo &Device::Info(Device *dev) Protocol::DeviceStatusV1 &Device::StatusV1() { + lock_guard guard(accessMutex); return status.v1; } @@ -467,6 +468,7 @@ const Protocol::DeviceStatusV1 &Device::StatusV1(Device *dev) QString Device::getLastDeviceInfoString() { + lock_guard guard(accessMutex); QString ret; if(!infoValid) { ret.append("No device information available yet"); @@ -521,18 +523,24 @@ void Device::ReceivedData() emit AmplitudeCorrectionPointReceived(packet.amplitudePoint); break; case Protocol::PacketType::DeviceInfo: - if(packet.info.ProtocolVersion != Protocol::Version) { - if(!infoValid) { - emit NeedsFirmwareUpdate(packet.info.ProtocolVersion, Protocol::Version); + { + lock_guard guard(accessMutex); + if(packet.info.ProtocolVersion != Protocol::Version) { + if(!infoValid) { + emit NeedsFirmwareUpdate(packet.info.ProtocolVersion, Protocol::Version); + } + } else { + info = packet.info; } - } else { - info = packet.info; + infoValid = true; } - infoValid = true; emit DeviceInfoUpdated(this); break; case Protocol::PacketType::DeviceStatusV1: - status.v1 = packet.statusV1; + { + lock_guard guard(accessMutex); + status.v1 = packet.statusV1; + } emit DeviceStatusUpdated(this); break; case Protocol::PacketType::Ack: diff --git a/Software/PC_Application/LibreVNA-GUI/Device/device.h b/Software/PC_Application/LibreVNA-GUI/Device/device.h index 4241f43..f59b8f8 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/device.h +++ b/Software/PC_Application/LibreVNA-GUI/Device/device.h @@ -140,6 +140,8 @@ private: union { Protocol::DeviceStatusV1 v1; } status; + + std::mutex accessMutex; }; #endif // DEVICE_H diff --git a/Software/PC_Application/LibreVNA-GUI/Device/deviceusblog.cpp b/Software/PC_Application/LibreVNA-GUI/Device/deviceusblog.cpp index d8c3605..dcb4fa1 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/deviceusblog.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/deviceusblog.cpp @@ -2,8 +2,12 @@ #include "preferences.h" +#include + #include +using namespace std; + DeviceUSBLog::DeviceUSBLog() : usedStorageSize(0) { @@ -18,6 +22,7 @@ DeviceUSBLog::~DeviceUSBLog() void DeviceUSBLog::reset() { + std::lock_guard guard(access); entries.clear(); usedStorageSize = 0; } @@ -64,8 +69,19 @@ void DeviceUSBLog::fromJSON(nlohmann::json j) } } +DeviceUSBLog::LogEntry DeviceUSBLog::getEntry(unsigned int index) +{ + std::lock_guard guard(access); + if(index < entries.size()) { + return entries[index]; + } else { + throw std::runtime_error("Index too high"); + } +} + void DeviceUSBLog::addEntry(const DeviceUSBLog::LogEntry &e) { + std::lock_guard guard(access); usedStorageSize += e.storageSize(); while(usedStorageSize > maxStorageSize) { usedStorageSize -= entries.front().storageSize(); @@ -75,9 +91,28 @@ void DeviceUSBLog::addEntry(const DeviceUSBLog::LogEntry &e) emit entryAdded(e); } -std::deque DeviceUSBLog::getEntries() const +unsigned long DeviceUSBLog::getMaxStorageSize() const { - return entries; + return maxStorageSize; +} + +unsigned long DeviceUSBLog::getUsedStorageSize() const +{ + return usedStorageSize; +} + +DeviceUSBLog::LogEntry::LogEntry(const DeviceUSBLog::LogEntry &e) +{ + timestamp = e.timestamp; + type = e.type; + serial = e.serial; + bytes = e.bytes; + if(e.p) { + p = new Protocol::PacketInfo; + *p = *e.p; + } else { + p = nullptr; + } } nlohmann::json DeviceUSBLog::LogEntry::toJSON() diff --git a/Software/PC_Application/LibreVNA-GUI/Device/deviceusblog.h b/Software/PC_Application/LibreVNA-GUI/Device/deviceusblog.h index 4a2f3ce..b56d4c6 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/deviceusblog.h +++ b/Software/PC_Application/LibreVNA-GUI/Device/deviceusblog.h @@ -9,6 +9,7 @@ #include #include #include +#include class DeviceUSBLog : public QObject, public Savable { @@ -34,6 +35,11 @@ public: public: LogEntry() : type(Type::InvalidBytes), timestamp(QDateTime()), serial(""), p(nullptr) {} + ~LogEntry() { + delete p; + } + + LogEntry(const LogEntry &e); enum class Type { Packet, @@ -57,7 +63,10 @@ public: virtual void fromJSON(nlohmann::json j) override; }; - std::deque getEntries() const; + LogEntry getEntry(unsigned int index); + + unsigned long getUsedStorageSize() const; + unsigned long getMaxStorageSize() const; signals: void entryAdded(const LogEntry &e); @@ -70,6 +79,8 @@ private: unsigned long maxStorageSize; unsigned long usedStorageSize; std::deque entries; + + std::mutex access; }; #endif // DEVICEUSBLOG_H diff --git a/Software/PC_Application/LibreVNA-GUI/Device/deviceusblogview.cpp b/Software/PC_Application/LibreVNA-GUI/Device/deviceusblogview.cpp index 0e0692f..b1bff6d 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/deviceusblogview.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/deviceusblogview.cpp @@ -82,9 +82,18 @@ void DeviceUSBLogView::updateTree() ui->tree->setColumnCount(4); ui->tree->setHeaderLabels({"Timestamp","Source","Type","Content"}); - for(auto &e : log.getEntries()) { - addEntry(e); + unsigned int i=0; + try { + // will throw once all entries have been added (number of entries may change while the loop is running) + for(i=0;;i++) { + addEntry(log.getEntry(i)); + } + } catch (...) { } + + QString status = "Log contains "+QString::number(i) + " entries, using "; + status += Unit::ToString(log.getUsedStorageSize(), "B", " kMG") + " (maximum: "+Unit::ToString(log.getMaxStorageSize(), "B", " kMG")+")"; + ui->status->setText(status); } void DeviceUSBLogView::addEntry(const DeviceUSBLog::LogEntry &e) diff --git a/Software/PC_Application/LibreVNA-GUI/Device/deviceusblogview.ui b/Software/PC_Application/LibreVNA-GUI/Device/deviceusblogview.ui index 63f325d..77b4b89 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/deviceusblogview.ui +++ b/Software/PC_Application/LibreVNA-GUI/Device/deviceusblogview.ui @@ -21,6 +21,13 @@ + + + + + + + diff --git a/Software/PC_Application/LibreVNA-GUI/Device/firmwareupdatedialog.cpp b/Software/PC_Application/LibreVNA-GUI/Device/firmwareupdatedialog.cpp index eb00a45..f2e5283 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/firmwareupdatedialog.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/firmwareupdatedialog.cpp @@ -61,8 +61,8 @@ void FirmwareUpdateDialog::on_bStart_clicked() } file->seek(0); state = State::ErasingFLASH; - connect(dev, &Device::AckReceived, this, &FirmwareUpdateDialog::receivedAck); - connect(dev, &Device::NackReceived, this, &FirmwareUpdateDialog::receivedNack); + connect(dev, &Device::AckReceived, this, &FirmwareUpdateDialog::receivedAck, Qt::QueuedConnection); + connect(dev, &Device::NackReceived, this, &FirmwareUpdateDialog::receivedNack, Qt::QueuedConnection); addStatus("Erasing device memory..."); dev->SendCommandWithoutPayload(Protocol::PacketType::ClearFlash); timer.setSingleShot(true); diff --git a/Software/PC_Application/LibreVNA-GUI/Device/manualcontroldialog.cpp b/Software/PC_Application/LibreVNA-GUI/Device/manualcontroldialog.cpp index 02d8e35..d9e31b6 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/manualcontroldialog.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/manualcontroldialog.cpp @@ -148,7 +148,7 @@ ManualControlDialog::ManualControlDialog(Device &dev, QWidget *parent) : MakeReadOnly(ui->refmag); MakeReadOnly(ui->refphase); - connect(&dev, &Device::ManualStatusReceived, this, &ManualControlDialog::NewStatus); + connect(&dev, &Device::ManualStatusReceived, this, &ManualControlDialog::NewStatus, Qt::QueuedConnection); connect(ui->SourceCE, &QCheckBox::toggled, [=](bool) { UpdateDevice(); }); connect(ui->SourceRFEN, &QCheckBox::toggled, [=](bool) { UpdateDevice(); }); diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.cpp b/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.cpp index ed69e6f..1477dea 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.cpp @@ -38,6 +38,7 @@ TracePlot::TracePlot(TraceModel &model, QWidget *parent) connect(&replotTimer, &QTimer::timeout, this, qOverload<>(&TracePlot::update)); sweep_fmin = std::numeric_limits::lowest(); sweep_fmax = std::numeric_limits::max(); + xSweep = std::numeric_limits::quiet_NaN(); // get notified when the span changes connect(&model, &TraceModel::SpanChanged, this, qOverload(&TracePlot::updateSpan)); plots.insert(this); diff --git a/Software/PC_Application/LibreVNA-GUI/appwindow.cpp b/Software/PC_Application/LibreVNA-GUI/appwindow.cpp index 23ceed1..d236ab4 100644 --- a/Software/PC_Application/LibreVNA-GUI/appwindow.cpp +++ b/Software/PC_Application/LibreVNA-GUI/appwindow.cpp @@ -939,6 +939,8 @@ void AppWindow::StartManualControl() void AppWindow::UpdateReferenceToolbar() { + toolbars.reference.type->blockSignals(true); + toolbars.reference.outFreq->blockSignals(true); if(!vdevice || !vdevice->getInfo().supportsExtRef) { toolbars.reference.type->setEnabled(false); toolbars.reference.outFreq->setEnabled(false); @@ -968,6 +970,9 @@ void AppWindow::UpdateReferenceToolbar() } else { toolbars.reference.outFreq->setCurrentIndex(0); } + toolbars.reference.type->blockSignals(false); + toolbars.reference.outFreq->blockSignals(false); + UpdateReference(); } void AppWindow::UpdateReference() @@ -1046,7 +1051,6 @@ void AppWindow::DeviceInfoUpdated() modeHandler->getActiveMode()->initializeDevice(); } UpdateReferenceToolbar(); - UpdateReference(); } void AppWindow::SourceCalibrationDialog()