Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix memory issues found using Valgrind ECFLOW-1969 #114

Merged
merged 12 commits into from
Sep 3, 2024
Merged
6 changes: 6 additions & 0 deletions Viewer/ecflowUI/src/ChangeNotify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ ChangeNotify::ChangeNotify(const std::string& id)
items[id] = this;
}

ChangeNotify::~ChangeNotify() {
delete data_;
delete model_;
delete proxyModel_;
}

ChangeNotifyModel* ChangeNotify::model() const {
return model_; // proxyModel_;
}
Expand Down
1 change: 1 addition & 0 deletions Viewer/ecflowUI/src/ChangeNotify.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class ChangeNotify : public VPropertyObserver {
explicit ChangeNotify(const std::string& id);
ChangeNotify(const ChangeNotify&) = delete;
ChangeNotify& operator=(const ChangeNotify&) = delete;
~ChangeNotify() override;

const std::string& id() const { return id_; }
VNodeList* data() const { return data_; }
Expand Down
2 changes: 1 addition & 1 deletion Viewer/ecflowUI/src/InfoPresenter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class VReply;
class InfoPresenter {
public:
InfoPresenter() = default;
virtual ~InfoPresenter() = default;
virtual ~InfoPresenter();
virtual void infoReady(VReply*) {}
virtual void infoFailed(VReply*) {}
virtual void infoProgress(VReply*) {}
Expand Down
8 changes: 7 additions & 1 deletion Viewer/ecflowUI/src/InfoProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
#include "ecflow/node/EcfFile.hpp"
#include "ecflow/node/Submittable.hpp"

InfoPresenter::~InfoPresenter() {
// The following takes care of deleting the provider used by this presenter.
// The provider is typically created in the ctor of derived class (e.g. WhyItemWidget)
delete infoProvider_;
}

InfoProvider::InfoProvider(InfoPresenter* owner, VTask::Type taskType)
: owner_(owner),
reply_(new VReply(this)),
Expand All @@ -30,8 +36,8 @@ InfoProvider::InfoProvider(InfoPresenter* owner, VTask::Type taskType)
}

InfoProvider::~InfoProvider() {
delete reply_;
clearInternal();
delete reply_;
}

void InfoProvider::clearInternal() {
Expand Down
2 changes: 2 additions & 0 deletions Viewer/ecflowUI/src/InfoProvider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ class InfoProvider : public VTaskObserver, public VInfoVisitor {
InfoProvider(InfoPresenter* owner, VTask::Type);
~InfoProvider() override;
InfoProvider(const InfoProvider&) = delete;
InfoProvider(InfoProvider&&) = delete;
InfoProvider& operator=(const InfoProvider&) = delete;
InfoProvider& operator=(InfoProvider&&) = delete;

void info(VInfo_ptr);
void command(VTask::Type);
Expand Down
4 changes: 3 additions & 1 deletion Viewer/ecflowUI/src/LogLoadWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ LogLoadWidget::LogLoadWidget(QWidget* /*parent*/) : ui_(new Ui::LogLoadWidget) {
slotExpandFileInfo(expandSt);
}

LogLoadWidget::~LogLoadWidget() = default;
LogLoadWidget::~LogLoadWidget() {
delete ui_;
}

// void LogLoadWidget::initSplitter()
//{
Expand Down
55 changes: 48 additions & 7 deletions Viewer/ecflowUI/src/ModelColumn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,56 @@
#include "VProperty.hpp"
#include "VSettingsLoader.hpp"

static std::map<std::string, ModelColumn*> defs;
class ColumnDefinitions {
public:
using storage_t = std::map<std::string, ModelColumn*>;

ColumnDefinitions(): storage_{} {}
~ColumnDefinitions() {
for(auto item: storage_) {
delete item.second;
}
}

void insert(const std::string& k, ModelColumn* v) {
storage_[k] = v;
}

auto find(const std::string& k) const {
return storage_.find(k);
}

auto end() {
return storage_.end();
}

template <typename F>
void for_each(F&& f) {
for(auto item: storage_) {
f(item.first, item.second);
}
}

private:
storage_t storage_;
};

static ColumnDefinitions defs;

ModelColumn::ModelColumn(const std::string& id) : id_(id), diagStart_(-1), diagEnd_(-1) {
defs[id_] = this;
defs.insert(id_, this);
}

ModelColumn::~ModelColumn() {
for(auto && item: items_) {
delete item;
}
}

ModelColumn* ModelColumn::def(const std::string& id) {
auto it = defs.find(id);
if (it != defs.end())
if (auto it = defs.find(id); it != defs.end()) {
return it->second;
}
return nullptr;
}

Expand Down Expand Up @@ -211,6 +251,9 @@ void ModelColumn::load(VProperty* group) {
Q_ASSERT(group);

auto* m = new ModelColumn(group->strName());
// Attention: Each ModelColumn object self-registers in `defs`!
// This means that the newly created object will live until `defs` (with static allocation) is released.

for (int i = 0; i < group->children().size(); i++) {
VProperty* p = group->children().at(i);
m->loadItem(p);
Expand All @@ -222,9 +265,7 @@ void ModelColumn::load(VProperty* group) {

// Called via VSettingsLoader after the users settings are read
void ModelColumn::loadSettings() {
for (auto& def : defs) {
def.second->loadUserSettings();
}
defs.for_each([](auto&& k, auto&& v){v->loadUserSettings();});
}

// Load user defined settings
Expand Down
1 change: 1 addition & 0 deletions Viewer/ecflowUI/src/ModelColumn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class ModelColumn : public QObject {
Q_OBJECT
public:
explicit ModelColumn(const std::string& id);
~ModelColumn() override;

int count() const { return items_.size(); }
int indexOf(QString) const;
Expand Down
1 change: 1 addition & 0 deletions Viewer/ecflowUI/src/NodeQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ NodeQuery::NodeQuery(const std::string& name, bool ignoreMaxNum)

NodeQuery::~NodeQuery() {
qDeleteAll(options_);
qDeleteAll(attrGroup_);
}

NodeQuery* NodeQuery::clone() {
Expand Down
6 changes: 4 additions & 2 deletions Viewer/ecflowUI/src/NodeQuery.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class NodeQueryAttrGroup {
: name_(name),
types_(types),
options_(options) {}
virtual ~NodeQueryAttrGroup() = default;

QString name() const { return name_; }
virtual bool hasType(VAttributeType* t) const { return types_.contains(t); }
Expand All @@ -41,14 +42,15 @@ class NodeQueryAttrGroup {

protected:
QString name_;
QList<VAttributeType*> types_;
QList<NodeQueryOption*> options_;
QList<VAttributeType*> types_; // This is a non-owning container
QList<NodeQueryOption*> options_; // This is a non-owning container
};

class NodeQueryVarAttrGroup : public NodeQueryAttrGroup {
public:
NodeQueryVarAttrGroup(QString name, QList<VAttributeType*> types, QList<NodeQueryOption*> options)
: NodeQueryAttrGroup(name, types, options) {}
~NodeQueryVarAttrGroup() override = default;

bool hasType(VAttributeType*) const override;
};
Expand Down
4 changes: 4 additions & 0 deletions Viewer/ecflowUI/src/OutputDirWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ OutputDirWidget::OutputDirWidget(QWidget* parent) : QWidget(parent), ui_(new Ui:
transitionTo(new DirWidgetEmptyState(this, nullptr));
}

OutputDirWidget::~OutputDirWidget() {
delete ui_;
}

// must be called externally
void OutputDirWidget::showIt(bool st) {
if (st) {
Expand Down
1 change: 1 addition & 0 deletions Viewer/ecflowUI/src/OutputDirWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class OutputDirWidget : public QWidget {

public:
explicit OutputDirWidget(QWidget* parent);
~OutputDirWidget() override;

void clear();
void load(VReply* reply, const std::string& joboutFile);
Expand Down
4 changes: 4 additions & 0 deletions Viewer/ecflowUI/src/OutputFetchInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ OutputFetchInfo::OutputFetchInfo(QWidget* parent) : QWidget(parent), ui_(new Ui:
connect(bGroup_, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*)));
}

OutputFetchInfo::~OutputFetchInfo() {
delete ui_;
}

void OutputFetchInfo::buttonClicked(QAbstractButton* b) {
ui_->stackedWidget->setCurrentIndex((b == ui_->infoTb) ? 0 : 1);
}
Expand Down
2 changes: 2 additions & 0 deletions Viewer/ecflowUI/src/OutputFetchInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class OutputFetchInfo : public QWidget {
Q_OBJECT
public:
explicit OutputFetchInfo(QWidget* parent);
~OutputFetchInfo() override;

void clearInfo();
void setInfo(VReply*, VInfo_ptr info = nullptr);
void setError(QString);
Expand Down
4 changes: 4 additions & 0 deletions Viewer/ecflowUI/src/PlainTextWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ PlainTextWidget::PlainTextWidget(QWidget* /*parent*/) : ui_(new Ui::PlainTextWid
connect(ui_->fontSizeDownTb, SIGNAL(clicked()), this, SLOT(slotFontSizeDown()));
}

PlainTextWidget::~PlainTextWidget() {
delete ui_;
}

void PlainTextWidget::setPlainText(QString t) {
ui_->textEdit->setPlainText(t);
}
Expand Down
2 changes: 1 addition & 1 deletion Viewer/ecflowUI/src/PlainTextWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class PlainTextWidget : public QWidget {

public:
explicit PlainTextWidget(QWidget* parent = nullptr);
~PlainTextWidget() override = default;
~PlainTextWidget() override;

void setPlainText(QString);
void setTitle(QString);
Expand Down
4 changes: 3 additions & 1 deletion Viewer/ecflowUI/src/TimelineView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ TimelineDelegate::TimelineDelegate(TimelineModel* model, QWidget* parent)
updateSettings();
}

TimelineDelegate::~TimelineDelegate() = default;
TimelineDelegate::~TimelineDelegate() {
delete prop_;
}

void TimelineDelegate::notifyChange(VProperty*) {
updateSettings();
Expand Down
4 changes: 2 additions & 2 deletions Viewer/ecflowUI/src/TimelineWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ TimelineWidget::TimelineWidget(QWidget* /*parent*/)
}

TimelineWidget::~TimelineWidget() {
if (data_)
delete data_;
delete data_;
delete ui_;
}

// a complete clear
Expand Down
6 changes: 5 additions & 1 deletion Viewer/ecflowUI/src/TreeNodeWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ TreeNodeWidget::TreeNodeWidget(ServerFilter* serverFilter, QWidget* parent)
WidgetNameProvider::nameChildren(this);
}

TreeNodeWidget::~TreeNodeWidget() = default;
TreeNodeWidget::~TreeNodeWidget() {
delete stateFilterMenu_;
delete attrFilterMenu_;
delete iconFilterMenu_;
}

void TreeNodeWidget::setViewLayoutMode(TreeNodeWidget::ViewLayoutMode mode) {
if (view_ && viewLayoutMode_ == mode)
Expand Down
1 change: 1 addition & 0 deletions Viewer/ecflowUI/src/TriggerGraphWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ TriggerGraphWidget::TriggerGraphWidget(QWidget* parent) : QWidget(parent), ui_(n

TriggerGraphWidget::~TriggerGraphWidget() {
clear();
delete ui_;
}

void TriggerGraphWidget::clear(bool keepConfig) {
Expand Down
8 changes: 5 additions & 3 deletions Viewer/ecflowUI/src/VConfigLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@
#include "VConfigLoader.hpp"

#include <map>
#include <memory>

using Map = std::multimap<std::string, VConfigLoader*>;

static Map* makers = nullptr;
static std::unique_ptr<Map> makers = nullptr;

VConfigLoader::VConfigLoader(const std::string& name) {
if (makers == nullptr)
makers = new Map();
if (!makers) {
makers = std::make_unique<Map>();
}

makers->insert(Map::value_type(name, this));
}
Expand Down
2 changes: 1 addition & 1 deletion Viewer/ecflowUI/src/WhyItemWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ WhyItemWidget::WhyItemWidget(QWidget* parent) : HtmlItemWidget(parent) {
fileLabel_->hide();

// Will be used for ECFLOW-901
infoProvider_ = new WhyProvider(this);
infoProvider_ = new WhyProvider(this); // populating InfoPresenter::infoProvider_, with the deletion later handled by InfoPresenter itself

textEdit_->setProperty("trigger", "1");
textEdit_->setFontProperty(VConfig::instance()->find("panel.why.font"));
Expand Down
5 changes: 5 additions & 0 deletions Viewer/ecflowUI/src/WhyItemWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ class WhyItemWidget : public HtmlItemWidget, public InfoPanelItem {

public:
explicit WhyItemWidget(QWidget* parent = nullptr);
WhyItemWidget(const WhyItemWidget&) = delete;
WhyItemWidget(WhyItemWidget&&) = delete;
~WhyItemWidget() override;

WhyItemWidget& operator=(const WhyItemWidget&) = delete;
WhyItemWidget& operator=(WhyItemWidget&&) = delete;

void reload(VInfo_ptr) override;
QWidget* realWidget() override;
void clearContents() override;
Expand Down
11 changes: 11 additions & 0 deletions Viewer/libViewer/src/IconProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,17 @@ QPixmap UnknownIconItem::unknown(int /*size*/) {

IconProvider::IconProvider() = default;

IconProvider::~IconProvider() {
// Important!
//
// The life time of the singleton instance 'iconProvider' is used to manage the life time of loaded Icons.
// This means that when the application closes, after main() has finished, the destruction of the instance clears the Icons.
//
for(auto icon : icons_) {
delete icon.second;
}
}

QString IconProvider::path(int id) {
auto it = iconsById_.find(id);
if (it != iconsById_.end())
Expand Down
1 change: 1 addition & 0 deletions Viewer/libViewer/src/IconProvider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class UnknownIconItem : public IconItem {
class IconProvider {
public:
IconProvider();
~IconProvider();

static int add(QString path, QString name);

Expand Down
7 changes: 4 additions & 3 deletions libs/client/src/ecflow/client/ClientOptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ class CommandLine;

class ClientOptions {
public:
ClientOptions(const ClientOptions&) = delete;
const ClientOptions& operator=(const ClientOptions&) = delete;

/// Will create command register, & ask each cmd to describe their arguments
ClientOptions();
ClientOptions(const ClientOptions&) = delete;
ClientOptions(ClientOptions&&) = delete;
ClientOptions& operator=(const ClientOptions&) = delete;
ClientOptions& operator=(ClientOptions&&) = delete;
~ClientOptions();

/// parse the arguments and create the client request that is to be sent
Expand Down
Loading
Loading