From d3370f5caff4d73d0f9354bdf693000b5ee62eeb Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee <elv1313@gmail.com> Date: Mon, 21 Dec 2015 07:49:46 -0500 Subject: [PATCH] credentials: Remove the union It was an experiment, it failed. The number of cache fault avoided by it is negligeable. It make debugging a pain and prevent the use of "new" and "delete". Then, there is still a crash in the freeing sequence. I could have fixed it, but would rather fix the cause: unions Issue: #80868 Change-Id: I107102f05d151055617fd4256e07ed5aaa196b2e --- src/credentialmodel.cpp | 115 +++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 67 deletions(-) diff --git a/src/credentialmodel.cpp b/src/credentialmodel.cpp index b5139da4..c6a9cbac 100644 --- a/src/credentialmodel.cpp +++ b/src/credentialmodel.cpp @@ -35,16 +35,10 @@ typedef void (CredentialModelPrivate::*CredModelFct)(); struct CredentialNode final { - union { - struct { - Credential* m_pCredential = {nullptr}; - CredentialNode* m_pParent = {nullptr}; - } m_Cred; - struct { - QString* m_CategoryName = {nullptr}; - QVector<CredentialNode*>* m_lChildren; - } m_Category; - } m_uContent; + Credential* m_pCredential {nullptr}; + CredentialNode* m_pParent {nullptr}; + QString* m_CategoryName {nullptr}; + QVector<CredentialNode*> m_lChildren ; enum class Level { CATEGORY, @@ -54,7 +48,6 @@ struct CredentialNode final short int m_Index = {-1}; Level m_Level; }; -void free_node(CredentialNode* n); /** * Display the types of credentials that can be added @@ -92,9 +85,9 @@ public: CredentialModel* q_ptr ; uint m_TopLevelCount = {3}; static Matrix2D<CredentialModel::EditState, CredentialModel::EditAction,CredModelFct> m_mStateMachine; - CredentialNode* m_pSipCat = {nullptr}; - CredentialNode* m_pTurnCat = {nullptr}; - CredentialNode* m_pStunCat = {nullptr}; + CredentialNode* m_pSipCat {nullptr}; + CredentialNode* m_pTurnCat {nullptr}; + CredentialNode* m_pStunCat {nullptr}; NewCredentialTypeModel* m_pTypeModel {nullptr}; //Callbacks @@ -136,7 +129,7 @@ d_ptr(new CredentialModelPrivate()) CredentialModel::~CredentialModel() { foreach (CredentialNode* data, d_ptr->m_lCategories) { - free(data); //delete doesn't support non-trivial structures + delete data; } } @@ -164,7 +157,7 @@ QModelIndex CredentialModel::parent( const QModelIndex& index) const if ((!node) || node->m_Level == CredentialNode::Level::CATEGORY) return QModelIndex(); - return createIndex(node->m_uContent.m_Cred.m_pParent->m_Index,0,node->m_uContent.m_Cred.m_pParent); + return createIndex(node->m_pParent->m_Index,0,node->m_pParent); } ///Get the column count @@ -184,10 +177,10 @@ QModelIndex CredentialModel::index( int row, int column, const QModelIndex& pare const CredentialNode* node = static_cast<CredentialNode*>(parent.internalPointer()); if (node->m_Level != CredentialNode::Level::CATEGORY - || row >= node->m_uContent.m_Category.m_lChildren->size()) + || row >= node->m_lChildren.size()) return QModelIndex(); - return createIndex(row, column, node->m_uContent.m_Category.m_lChildren->at(row)); + return createIndex(row, column, node->m_lChildren.at(row)); } if (row >= d_ptr->m_lCategories.size()) @@ -207,18 +200,18 @@ QVariant CredentialModel::data(const QModelIndex& idx, int role) const { case CredentialNode::Level::CATEGORY: switch(role) { case Qt::DisplayRole: - return *node->m_uContent.m_Category.m_CategoryName; + return *node->m_CategoryName; } break; case CredentialNode::Level::CREDENTIAL: switch (role) { case Qt::DisplayRole: case CredentialModel::Role::NAME: - return node->m_uContent.m_Cred.m_pCredential->username(); + return node->m_pCredential->username(); case CredentialModel::Role::PASSWORD: - return node->m_uContent.m_Cred.m_pCredential->password(); + return node->m_pCredential->password(); case CredentialModel::Role::REALM: - return node->m_uContent.m_Cred.m_pCredential->realm(); + return node->m_pCredential->realm(); default: break; } @@ -237,7 +230,7 @@ int CredentialModel::rowCount(const QModelIndex& par) const { if (node->m_Level == CredentialNode::Level::CREDENTIAL) return 0; - return d_ptr->m_lCategories[par.row()]->m_uContent.m_Category.m_lChildren->size(); + return d_ptr->m_lCategories[par.row()]->m_lChildren.size(); } ///Model flags @@ -270,21 +263,21 @@ bool CredentialModel::setData( const QModelIndex& idx, const QVariant &value, in return false; if (idx.column() == 0 && role == CredentialModel::Role::NAME) { - node->m_uContent.m_Cred.m_pCredential->setUsername(value.toString()); + node->m_pCredential->setUsername(value.toString()); emit dataChanged(idx, idx); this << EditAction::MODIFY; return true; } else if (idx.column() == 0 && role == CredentialModel::Role::PASSWORD) { - if (node->m_uContent.m_Cred.m_pCredential->password() != value.toString()) { - node->m_uContent.m_Cred.m_pCredential->setPassword(value.toString()); + if (node->m_pCredential->password() != value.toString()) { + node->m_pCredential->setPassword(value.toString()); emit dataChanged(idx, idx); this << EditAction::MODIFY; return true; } } else if (idx.column() == 0 && role == CredentialModel::Role::REALM) { - node->m_uContent.m_Cred.m_pCredential->setRealm(value.toString()); + node->m_pCredential->setRealm(value.toString()); emit dataChanged(idx, idx); this << EditAction::MODIFY; return true; @@ -294,11 +287,10 @@ bool CredentialModel::setData( const QModelIndex& idx, const QVariant &value, in CredentialNode* CredentialModelPrivate::createCat(const QString& name) { - CredentialNode* n = (CredentialNode*) malloc(sizeof(CredentialNode)); + CredentialNode* n = new CredentialNode(); n->m_Level = CredentialNode::Level::CATEGORY; n->m_Index = q_ptr->rowCount(); - n->m_uContent.m_Category.m_CategoryName = new QString(name); - n->m_uContent.m_Category.m_lChildren = new QVector<CredentialNode*>(); + n->m_CategoryName = new QString(name); q_ptr->beginInsertRows(QModelIndex(),m_lCategories.size(),0); m_lCategories << n; @@ -307,20 +299,6 @@ CredentialNode* CredentialModelPrivate::createCat(const QString& name) return n; } -void free_node(CredentialNode* n) -{ - switch (n->m_Level) { - case CredentialNode::Level::CATEGORY: - delete n->m_uContent.m_Category.m_CategoryName; - delete n->m_uContent.m_Category.m_lChildren; - break; - case CredentialNode::Level::CREDENTIAL: - delete n->m_uContent.m_Cred.m_pCredential; - break; - } - free(n); -} - CredentialNode* CredentialModelPrivate::getCategory(Credential::Type type) { switch (type) { @@ -361,24 +339,24 @@ QModelIndex CredentialModel::addCredentials() QModelIndex CredentialModel::addCredentials(Credential::Type type) { CredentialNode* par = d_ptr->getCategory(type); - const int count = par->m_uContent.m_Category.m_lChildren->size(); + const int count = par->m_lChildren.size(); const QModelIndex parIdx = index(par->m_Index,0); beginInsertRows(parIdx, count, count); - CredentialNode* node = (CredentialNode*) malloc(sizeof(CredentialNode)); + CredentialNode* node = new CredentialNode(); node->m_Level = CredentialNode::Level::CREDENTIAL; - node->m_uContent.m_Cred.m_pCredential = new Credential(type); - node->m_uContent.m_Cred.m_pParent = par; - node->m_Index = par->m_uContent.m_Category.m_lChildren->size(); - par->m_uContent.m_Category.m_lChildren->append(node); + node->m_pCredential = new Credential(type); + node->m_pParent = par; + node->m_Index = par->m_lChildren.size(); + par->m_lChildren.append(node); - connect(node->m_uContent.m_Cred.m_pCredential, &Credential::changed,[this, node, par, type]() { + connect(node->m_pCredential, &Credential::changed,[this, node, par, type]() { const QModelIndex parIdx = index(par->m_Index,0); const QModelIndex idx = index(node->m_Index,0,parIdx); emit dataChanged(idx, idx); if (!node->m_Index) { - Credential* c = node->m_uContent.m_Cred.m_pCredential; + Credential* c = node->m_pCredential; emit primaryCredentialChanged(type, c); } }); @@ -398,11 +376,11 @@ void CredentialModel::removeCredentials(const QModelIndex& idx) CredentialNode* node = static_cast<CredentialNode*>(idx.internalPointer()); - for (int i = node->m_Index+1; i < node->m_uContent.m_Cred.m_pParent->m_uContent.m_Category.m_lChildren->size();i++) { - node->m_uContent.m_Cred.m_pParent->m_uContent.m_Category.m_lChildren->at(i)->m_Index--; + for (int i = node->m_Index+1; i < node->m_pParent->m_lChildren.size();i++) { + node->m_pParent->m_lChildren.at(i)->m_Index--; } - node->m_uContent.m_Cred.m_pParent->m_uContent.m_Category.m_lChildren->removeAt(node->m_Index); - free_node(node); + node->m_pParent->m_lChildren.removeAt(node->m_Index); + delete node; endRemoveRows(); this << EditAction::MODIFY; @@ -416,8 +394,11 @@ void CredentialModel::removeCredentials(const QModelIndex& idx) void CredentialModelPrivate::clear() { q_ptr->beginRemoveRows(QModelIndex(),0,q_ptr->rowCount()); + m_pSipCat = nullptr; + m_pTurnCat = nullptr; + m_pSipCat = nullptr; foreach(CredentialNode* data2, m_lCategories) { - free_node(data2); + delete data2; } m_lCategories.clear(); q_ptr->endRemoveRows(); @@ -433,8 +414,8 @@ void CredentialModelPrivate::save() if (m_pSipCat) { VectorMapStringString toReturn; - foreach (CredentialNode* n, *m_pSipCat->m_uContent.m_Category.m_lChildren) { - Credential* cred = n->m_uContent.m_Cred.m_pCredential; + foreach (CredentialNode* n, m_pSipCat->m_lChildren) { + Credential* cred = n->m_pCredential; if (cred->username().isEmpty()) cred->setUsername(m_pAccount->username()); @@ -453,8 +434,8 @@ void CredentialModelPrivate::save() //TURN creds if (m_pTurnCat) { - foreach (CredentialNode* n, *m_pSipCat->m_uContent.m_Category.m_lChildren) { - Credential* cred = n->m_uContent.m_Cred.m_pCredential; + foreach (CredentialNode* n, m_pSipCat->m_lChildren) { + Credential* cred = n->m_pCredential; m_pAccount->d_ptr->setAccountProperty(DRing::Account::ConfProperties::TURN::SERVER_UNAME , cred->username()); m_pAccount->d_ptr->setAccountProperty(DRing::Account::ConfProperties::TURN::SERVER_PWD , cred->password()); @@ -538,16 +519,16 @@ Credential* CredentialModel::primaryCredential(Credential::Type type) const { switch(type) { case Credential::Type::STUN: - if (d_ptr->m_pStunCat && d_ptr->m_pStunCat->m_uContent.m_Category.m_lChildren->size()) - return d_ptr->m_pStunCat->m_uContent.m_Category.m_lChildren->first()->m_uContent.m_Cred.m_pCredential; + if (d_ptr->m_pStunCat && d_ptr->m_pStunCat->m_lChildren.size()) + return d_ptr->m_pStunCat->m_lChildren.first()->m_pCredential; break; case Credential::Type::TURN: - if (d_ptr->m_pTurnCat && d_ptr->m_pTurnCat->m_uContent.m_Category.m_lChildren->size()) - return d_ptr->m_pTurnCat->m_uContent.m_Category.m_lChildren->first()->m_uContent.m_Cred.m_pCredential; + if (d_ptr->m_pTurnCat && d_ptr->m_pTurnCat->m_lChildren.size()) + return d_ptr->m_pTurnCat->m_lChildren.first()->m_pCredential; break; case Credential::Type::SIP: - if (d_ptr->m_pSipCat && d_ptr->m_pSipCat->m_uContent.m_Category.m_lChildren->size()) - return d_ptr->m_pSipCat->m_uContent.m_Category.m_lChildren->first()->m_uContent.m_Cred.m_pCredential; + if (d_ptr->m_pSipCat && d_ptr->m_pSipCat->m_lChildren.size()) + return d_ptr->m_pSipCat->m_lChildren.first()->m_pCredential; break; case Credential::Type::COUNT__: break; -- GitLab