Merge pull request #499 from qurrent-llc/fix_addframebadalloc
Fix frames and filteredFrames from growing until out of memory
This commit is contained in:
+46
-10
@@ -4,6 +4,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QSettings>
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
CANFrameModel::~CANFrameModel()
|
CANFrameModel::~CANFrameModel()
|
||||||
@@ -45,18 +46,21 @@ int CANFrameModel::columnCount(const QModelIndex &index) const
|
|||||||
CANFrameModel::CANFrameModel(QObject *parent)
|
CANFrameModel::CANFrameModel(QObject *parent)
|
||||||
: QAbstractTableModel(parent)
|
: QAbstractTableModel(parent)
|
||||||
{
|
{
|
||||||
|
int maxFramesDefault;
|
||||||
if (QSysInfo::WordSize > 32)
|
if (QSysInfo::WordSize > 32)
|
||||||
{
|
{
|
||||||
qDebug() << "64 bit OS detected. Requesting a large preallocation";
|
qDebug() << "64 bit OS detected. Requesting a large preallocation";
|
||||||
preallocSize = 10000000;
|
maxFramesDefault = 10000000;
|
||||||
}
|
}
|
||||||
else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down.
|
else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down.
|
||||||
{
|
{
|
||||||
qDebug() << "32 bit OS detected. Requesting a much restricted prealloc";
|
qDebug() << "32 bit OS detected. Requesting a much restricted prealloc";
|
||||||
preallocSize = 2000000;
|
maxFramesDefault = 2000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSettings settings;
|
||||||
|
preallocSize = settings.value("Main/MaximumFrames", maxFramesDefault).toInt();
|
||||||
|
|
||||||
frames.reserve(preallocSize);
|
frames.reserve(preallocSize);
|
||||||
filteredFrames.reserve(preallocSize); //the goal is to prevent a reallocation from ever happening
|
filteredFrames.reserve(preallocSize); //the goal is to prevent a reallocation from ever happening
|
||||||
|
|
||||||
@@ -673,13 +677,31 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
|
|||||||
|
|
||||||
if (!overwriteDups)
|
if (!overwriteDups)
|
||||||
{
|
{
|
||||||
frames.append(tempFrame);
|
bool alloc_ok = true;
|
||||||
if (filters[tempFrame.frameId()] && busFilters[tempFrame.bus])
|
|
||||||
|
for(int i=0; i<3; i++)
|
||||||
{
|
{
|
||||||
if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count());
|
try
|
||||||
tempFrame.frameCount = 1;
|
{
|
||||||
filteredFrames.append(tempFrame);
|
frames.append(tempFrame);
|
||||||
if (autoRefresh) endInsertRows();
|
break;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
alloc_ok = false;
|
||||||
|
qDebug() << "addFrame failed to append. frames.length(): " << frames.length() << " Exception: " << ex.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(alloc_ok)
|
||||||
|
{
|
||||||
|
if (filters[tempFrame.frameId()] && busFilters[tempFrame.bus])
|
||||||
|
{
|
||||||
|
if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count());
|
||||||
|
tempFrame.frameCount = 1;
|
||||||
|
filteredFrames.append(tempFrame);
|
||||||
|
if (autoRefresh) endInsertRows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //yes, overwrite dups
|
else //yes, overwrite dups
|
||||||
@@ -728,6 +750,20 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
|
|||||||
|
|
||||||
void CANFrameModel::addFrames(const CANConnection*, const QVector<CANFrame>& pFrames)
|
void CANFrameModel::addFrames(const CANConnection*, const QVector<CANFrame>& pFrames)
|
||||||
{
|
{
|
||||||
|
if(frames.length() > frames.capacity() * 0.99)
|
||||||
|
{
|
||||||
|
qDebug() << "Frames count: " << frames.length() << " of " << frames.capacity() << " capacity, removing first " << (int)(frames.capacity() * 0.05) << " frames";
|
||||||
|
frames.remove(0, (int)(frames.capacity() * 0.05));
|
||||||
|
qDebug() << "Frames removed, new count: " << frames.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(filteredFrames.length() > filteredFrames.capacity() * 0.99)
|
||||||
|
{
|
||||||
|
qDebug() << "filteredFrames count: " << filteredFrames.length() << " of " << filteredFrames.capacity() << " capacity, removing first " << (int)(filteredFrames.capacity() * 0.05) << " frames";
|
||||||
|
filteredFrames.remove(0, (int)(filteredFrames.capacity() * 0.05));
|
||||||
|
qDebug() << "filteredFrames removed, new count: " << filteredFrames.length();
|
||||||
|
}
|
||||||
|
|
||||||
foreach(const CANFrame& frame, pFrames)
|
foreach(const CANFrame& frame, pFrames)
|
||||||
{
|
{
|
||||||
addFrame(frame);
|
addFrame(frame);
|
||||||
@@ -754,8 +790,8 @@ void CANFrameModel::sendRefresh()
|
|||||||
mutex.lock();
|
mutex.lock();
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
filteredFrames.clear();
|
filteredFrames.clear();
|
||||||
filteredFrames.reserve(preallocSize);
|
|
||||||
filteredFrames.append(tempContainer);
|
filteredFrames.append(tempContainer);
|
||||||
|
filteredFrames.reserve(preallocSize);
|
||||||
|
|
||||||
lastUpdateNumFrames = 0;
|
lastUpdateNumFrames = 0;
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
|||||||
@@ -90,6 +90,20 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
|||||||
ui->cbFilterLabeling->setChecked(settings.value("Main/FilterLabeling", true).toBool());
|
ui->cbFilterLabeling->setChecked(settings.value("Main/FilterLabeling", true).toBool());
|
||||||
ui->cbIgnoreDBCColors->setChecked(settings.value("Main/IgnoreDBCColors", false).toBool());
|
ui->cbIgnoreDBCColors->setChecked(settings.value("Main/IgnoreDBCColors", false).toBool());
|
||||||
|
|
||||||
|
int maxFramesDefault;
|
||||||
|
if (QSysInfo::WordSize > 32)
|
||||||
|
{
|
||||||
|
qDebug() << "64 bit OS detected. Requesting a large preallocation";
|
||||||
|
maxFramesDefault = 10000000;
|
||||||
|
}
|
||||||
|
else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down.
|
||||||
|
{
|
||||||
|
qDebug() << "32 bit OS detected. Requesting a much restricted prealloc";
|
||||||
|
maxFramesDefault = 2000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->spinMaximumFrames->setValue(settings.value("Main/MaximumFrames", maxFramesDefault).toInt());
|
||||||
|
|
||||||
//just for simplicity they all call the same function and that function updates all settings at once
|
//just for simplicity they all call the same function and that function updates all settings at once
|
||||||
connect(ui->cbDisplayHex, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
connect(ui->cbDisplayHex, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||||
connect(ui->cbFlowAutoRef, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
connect(ui->cbFlowAutoRef, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||||
@@ -117,6 +131,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) :
|
|||||||
connect(ui->cbHexGraphFlow, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
connect(ui->cbHexGraphFlow, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||||
connect(ui->cbHexGraphInfo, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
connect(ui->cbHexGraphInfo, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||||
connect(ui->cbIgnoreDBCColors, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
connect(ui->cbIgnoreDBCColors, SIGNAL(toggled(bool)), this, SLOT(updateSettings()));
|
||||||
|
connect(ui->spinMaximumFrames, SIGNAL(valueChanged(int)), this, SLOT(updateSettings()));
|
||||||
|
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
}
|
}
|
||||||
@@ -183,6 +198,7 @@ void MainSettingsDialog::updateSettings()
|
|||||||
settings.setValue("Remote/Pass", encPass);
|
settings.setValue("Remote/Pass", encPass);
|
||||||
settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked());
|
settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked());
|
||||||
settings.setValue("Main/IgnoreDBCColors", ui->cbIgnoreDBCColors->isChecked());
|
settings.setValue("Main/IgnoreDBCColors", ui->cbIgnoreDBCColors->isChecked());
|
||||||
|
settings.setValue("Main/MaximumFrames", ui->spinMaximumFrames->value());
|
||||||
|
|
||||||
settings.sync();
|
settings.sync();
|
||||||
emit updatedSettings();
|
emit updatedSettings();
|
||||||
|
|||||||
@@ -80,6 +80,39 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum Frames to Capture</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinMaximumFrames">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>100000</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>1000000000</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>100000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>10000000</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_6">
|
<widget class="QGroupBox" name="groupBox_6">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
|||||||
Reference in New Issue
Block a user