diff --git a/src/cdextraprotocol.cpp b/src/cdextraprotocol.cpp index 7a400fe..be1a31d 100644 --- a/src/cdextraprotocol.cpp +++ b/src/cdextraprotocol.cpp @@ -339,9 +339,9 @@ void CDextraProtocol::HandleKeepalives(void) // iterate on peers CPeers *peers = g_Reflector.GetPeers(); - int index = -1; + auto pit = peers->begin(); CPeer *peer = NULL; - while ( (peer = peers->FindNextPeer(PROTOCOL_DEXTRA, &index)) != NULL ) + while ( (peer = peers->FindNextPeer(PROTOCOL_DEXTRA, pit)) != NULL ) { // keepalives are sent between clients @@ -379,9 +379,9 @@ void CDextraProtocol::HandlePeerLinks(void) // check if all our connected peers are still listed by gatekeeper // if not, disconnect - int index = -1; + auto pit = peers->begin(); CPeer *peer = NULL; - while ( (peer = peers->FindNextPeer(PROTOCOL_DEXTRA, &index)) != NULL ) + while ( (peer = peers->FindNextPeer(PROTOCOL_DEXTRA, pit)) != NULL ) { if ( list->FindListItem(peer->GetCallsign()) == NULL ) { diff --git a/src/cpeers.cpp b/src/cpeers.cpp index be7e9eb..f631a22 100644 --- a/src/cpeers.cpp +++ b/src/cpeers.cpp @@ -32,10 +32,7 @@ // constructor -CPeers::CPeers() -{ - m_Peers.reserve(100); -} +CPeers::CPeers() {} //////////////////////////////////////////////////////////////////////////////////////// // destructors @@ -43,14 +40,9 @@ CPeers::CPeers() CPeers::~CPeers() { m_Mutex.lock(); - { - for ( int i = 0; i < m_Peers.size(); i++ ) - { - delete m_Peers[i]; - } - m_Peers.clear(); - - } + for (auto it=begin(); it!=end(); it++ ) + delete *it; + m_Peers.clear(); m_Mutex.unlock(); } @@ -60,93 +52,68 @@ CPeers::~CPeers() void CPeers::AddPeer(CPeer *peer) { // first check if peer already exists - bool found = false; - for ( int i = 0; (i < m_Peers.size()) && !found; i++ ) + for ( auto it=begin(); it!=end(); it++ ) { - found = (*peer == *m_Peers[i]); + if (*peer == *(*it)) // if found, just do nothing // so *peer keep pointing on a valid object // on function return - if ( found ) { // delete new one delete peer; - //std::cout << "Adding existing peer " << peer->GetCallsign() << " at " << peer->GetIp() << std::endl; + return; } } // if not, append to the vector - if ( !found ) - { - // grow vector capacity if needed - if ( m_Peers.capacity() == m_Peers.size() ) - { - m_Peers.reserve(m_Peers.capacity()+10); - } - // append peer to reflector peer list - m_Peers.push_back(peer); - std::cout << "New peer " << peer->GetCallsign() << " at " << peer->GetIp() - << " added with protocol " << peer->GetProtocolName() << std::endl; - // and append all peer's client to reflector client list - // it is double lock safe to lock Clients list after Peers list - CClients *clients = g_Reflector.GetClients(); - for ( auto cit=peer->cbegin(); cit!=peer->cend(); cit++ ) - { - clients->AddClient(*cit); - } - g_Reflector.ReleaseClients(); - - // notify - g_Reflector.OnPeersChanged(); - } + m_Peers.push_back(peer); + std::cout << "New peer " << peer->GetCallsign() << " at " << peer->GetIp() + << " added with protocol " << peer->GetProtocolName() << std::endl; + // and append all peer's client to reflector client list + // it is double lock safe to lock Clients list after Peers list + CClients *clients = g_Reflector.GetClients(); + for ( auto cit=peer->cbegin(); cit!=peer->cend(); cit++ ) + { + clients->AddClient(*cit); + } + g_Reflector.ReleaseClients(); + + // notify + g_Reflector.OnPeersChanged(); } void CPeers::RemovePeer(CPeer *peer) { // look for the client - bool found = false; - for ( int i = 0; (i < m_Peers.size()) && !found; i++ ) + for ( auto pit=begin(); pit!=end(); /*increment done in body */ ) { // compare object pointers - if ( (m_Peers[i]) == peer ) - { - // found it ! - if ( !m_Peers[i]->IsAMaster() ) - { - // remove all clients from reflector client list - // it is double lock safe to lock Clients list after Peers list - CClients *clients = g_Reflector.GetClients(); - for ( auto cit=peer->begin(); cit!=peer->end(); cit++ ) - { - // this also delete the client object - clients->RemoveClient(*cit); - } - // so clear it then - m_Peers[i]->ClearClients(); - g_Reflector.ReleaseClients(); - - // remove it - std::cout << "Peer " << m_Peers[i]->GetCallsign() << " at " << m_Peers[i]->GetIp() - << " removed" << std::endl; - delete m_Peers[i]; - m_Peers.erase(m_Peers.begin()+i); - found = true; - // notify - g_Reflector.OnPeersChanged(); - } - } - } -} - -CPeer *CPeers::GetPeer(int i) -{ - if ( (i >= 0) && (i < m_Peers.size()) ) - { - return m_Peers[i]; - } - else - { - return NULL; + if (( *pit == peer ) && ( !(*pit)->IsAMaster() )) + { + // remove all clients from reflector client list + // it is double lock safe to lock Clients list after Peers list + CClients *clients = g_Reflector.GetClients(); + for ( auto cit=peer->begin(); cit!=peer->end(); cit++ ) + { + // this also delete the client object + clients->RemoveClient(*cit); + } + // so clear it then + (*pit)->ClearClients(); + g_Reflector.ReleaseClients(); + + // remove it + std::cout << "Peer " << (*pit)->GetCallsign() << " at " << (*pit)->GetIp() + << " removed" << std::endl; + delete *pit; + pit = m_Peers.erase(pit); + // notify + g_Reflector.OnPeersChanged(); + } + else + { + pit++; + } } } @@ -155,76 +122,59 @@ CPeer *CPeers::GetPeer(int i) CPeer *CPeers::FindPeer(const CIp &Ip, int Protocol) { - CPeer *peer = NULL; - - // find peer - for ( int i = 0; (i < m_Peers.size()) && (peer == NULL); i++ ) + for ( auto it=begin(); it!=end(); it++ ) { - if ( (m_Peers[i]->GetIp() == Ip) && (m_Peers[i]->GetProtocol() == Protocol)) + if ( ((*it)->GetIp() == Ip) && ((*it)->GetProtocol() == Protocol)) { - peer = m_Peers[i]; + return *it; } } - // done - return peer; + return NULL; } CPeer *CPeers::FindPeer(const CCallsign &Callsign, const CIp &Ip, int Protocol) { - CPeer *peer = NULL; - - // find peer - for ( int i = 0; (i < m_Peers.size()) && (peer == NULL); i++ ) + for ( auto it=begin(); it!=end(); it++ ) { - if ( m_Peers[i]->GetCallsign().HasSameCallsign(Callsign) && - (m_Peers[i]->GetIp() == Ip) && - (m_Peers[i]->GetProtocol() == Protocol) ) + if ( (*it)->GetCallsign().HasSameCallsign(Callsign) && + ((*it)->GetIp() == Ip) && + ((*it)->GetProtocol() == Protocol) ) { - peer = m_Peers[i]; + return *it; } } - // done - return peer; + return NULL; } CPeer *CPeers::FindPeer(const CCallsign &Callsign, int Protocol) { - CPeer *peer = NULL; - - // find peer - for ( int i = 0; (i < m_Peers.size()) && (peer == NULL); i++ ) + for ( auto it=begin(); it!=end(); it++ ) { - if ( (m_Peers[i]->GetProtocol() == Protocol) && - m_Peers[i]->GetCallsign().HasSameCallsign(Callsign) ) + if ( ((*it)->GetProtocol() == Protocol) && + (*it)->GetCallsign().HasSameCallsign(Callsign) ) { - peer = m_Peers[i]; + return *it; } } - // done - return peer; + return NULL; } //////////////////////////////////////////////////////////////////////////////////////// // iterate on peers -CPeer *CPeers::FindNextPeer(int Protocol, int *index) +CPeer *CPeers::FindNextPeer(int Protocol, std::list::iterator &it) { - CPeer *peer = NULL; - - // find next peer - bool found = false; - for ( int i = *index+1; (i < m_Peers.size()) && !found; i++ ) + while ( it!=end() ) { - if ( m_Peers[i]->GetProtocol() == Protocol ) + if ( (*it)->GetProtocol() == Protocol ) { - found = true; - peer = m_Peers[i]; - *index = i; + return *it++; } + it++; } - return peer; + return NULL; } diff --git a/src/cpeers.h b/src/cpeers.h index 65e4514..d9b037f 100644 --- a/src/cpeers.h +++ b/src/cpeers.h @@ -4,6 +4,7 @@ // // Created by Jean-Luc Deltombe (LX3JL) on 10/12/2016. // Copyright © 2016 Jean-Luc Deltombe (LX3JL). All rights reserved. +// Copyright © 2020 Thomas A. Early, N7TAE // // ---------------------------------------------------------------------------- // This file is part of xlxd. @@ -40,32 +41,37 @@ class CPeers public: // constructors CPeers(); - + // destructors virtual ~CPeers(); - + // locks void Lock(void) { m_Mutex.lock(); } void Unlock(void) { m_Mutex.unlock(); } - + // manage peers int GetSize(void) const { return (int)m_Peers.size(); } void AddPeer(CPeer *); void RemovePeer(CPeer *); - CPeer *GetPeer(int); - + + // pass-thru + std::list::iterator begin() { return m_Peers.begin(); } + std::list::iterator end() { return m_Peers.end(); } + std::list::const_iterator cbegin() const { return m_Peers.cbegin(); } + std::list::const_iterator cend() const { return m_Peers.cend(); } + // find peers CPeer *FindPeer(const CIp &, int); CPeer *FindPeer(const CCallsign &, const CIp &, int); CPeer *FindPeer(const CCallsign &, int); // iterate on peers - CPeer *FindNextPeer(int, int*); + CPeer *FindNextPeer(int, std::list::iterator &); protected: // data - std::mutex m_Mutex; - std::vector m_Peers; + std::mutex m_Mutex; + std::list m_Peers; }; diff --git a/src/creflector.cpp b/src/creflector.cpp index 80257bb..9acf714 100644 --- a/src/creflector.cpp +++ b/src/creflector.cpp @@ -4,6 +4,7 @@ // // Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015. // Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. +// Copyright © 2020 Thomas A. Early, N7TAE // // ---------------------------------------------------------------------------- // This file is part of xlxd. @@ -617,9 +618,9 @@ void CReflector::WriteXmlFile(std::ofstream &xmlFile) // lock CPeers *peers = GetPeers(); // iterate on peers - for ( int i = 0; i < peers->GetSize(); i++ ) + for ( auto pit=peers->cbegin(); pit!=peers->cend(); pit++ ) { - peers->GetPeer(i)->WriteXml(xmlFile); + (*pit)->WriteXml(xmlFile); } // unlock ReleasePeers(); @@ -630,11 +631,11 @@ void CReflector::WriteXmlFile(std::ofstream &xmlFile) // lock CClients *clients = GetClients(); // iterate on clients - for ( auto it=clients->cbegin(); it!=clients->cend(); it++ ) + for ( auto cit=clients->cbegin(); cit!=clients->cend(); cit++ ) { - if ( (*it)->IsNode() ) + if ( (*cit)->IsNode() ) { - (*it)->WriteXml(xmlFile); + (*cit)->WriteXml(xmlFile); } } // unlock diff --git a/src/cxlxprotocol.cpp b/src/cxlxprotocol.cpp index 06927af..26a022f 100644 --- a/src/cxlxprotocol.cpp +++ b/src/cxlxprotocol.cpp @@ -323,9 +323,9 @@ void CXlxProtocol::HandleKeepalives(void) // iterate on peers CPeers *peers = g_Reflector.GetPeers(); - int index = -1; + auto pit = peers->begin(); CPeer *peer = NULL; - while ( (peer = peers->FindNextPeer(PROTOCOL_XLX, &index)) != NULL ) + while ( (peer = peers->FindNextPeer(PROTOCOL_XLX, pit)) != NULL ) { // send keepalive m_Socket.Send(keepalive, peer->GetIp()); @@ -365,9 +365,9 @@ void CXlxProtocol::HandlePeerLinks(void) // check if all our connected peers are still listed by gatekeeper // if not, disconnect - int index = -1; + auto pit = peers->begin(); CPeer *peer = NULL; - while ( (peer = peers->FindNextPeer(PROTOCOL_XLX, &index)) != NULL ) + while ( (peer = peers->FindNextPeer(PROTOCOL_XLX, pit)) != NULL ) { if ( list->FindListItem(peer->GetCallsign()) == NULL ) {