use std::atomic<std::shared_ptr<...>> instead boost::shared_ptr if applicable

This commit is contained in:
orignal 2024-09-08 16:30:27 -04:00
parent ba451eeca5
commit cd648b9b3f
3 changed files with 84 additions and 66 deletions

View File

@ -127,12 +127,12 @@ namespace data
}
bool PopulateRouterInfoBuffer (std::shared_ptr<RouterInfo> r);
std::shared_ptr<RouterInfo::Address> NewRouterInfoAddress () { return m_RouterInfoAddressesPool.AcquireSharedMt (); };
boost::shared_ptr<RouterInfo::Addresses> NewRouterInfoAddresses ()
RouterInfo::AddressesPtr NewRouterInfoAddresses ()
{
return boost::shared_ptr<RouterInfo::Addresses>(m_RouterInfoAddressVectorsPool.AcquireMt (),
return RouterInfo::AddressesPtr{m_RouterInfoAddressVectorsPool.AcquireMt (),
std::bind <void (i2p::util::MemoryPoolMt<RouterInfo::Addresses>::*)(RouterInfo::Addresses *)>
(&i2p::util::MemoryPoolMt<RouterInfo::Addresses>::ReleaseMt,
&m_RouterInfoAddressVectorsPool, std::placeholders::_1));
&m_RouterInfoAddressVectorsPool, std::placeholders::_1)};
};
std::shared_ptr<Lease> NewLease (const Lease& lease) { return m_LeasesPool.AcquireSharedMt (lease); };
std::shared_ptr<IdentityEx> NewIdentity (const uint8_t * buf, size_t len) { return m_IdentitiesPool.AcquireSharedMt (buf, len); };

View File

@ -10,10 +10,10 @@
#include <string.h>
#include "I2PEndian.h"
#include <fstream>
#include <memory>
#include <boost/lexical_cast.hpp>
#include <boost/make_shared.hpp>
#include <boost/algorithm/string.hpp> // for boost::to_lower
#if (BOOST_VERSION >= 105300)
#ifndef __cpp_lib_atomic_shared_ptr
#include <boost/atomic.hpp>
#endif
#include "version.h"
@ -40,7 +40,7 @@ namespace data
RouterInfo::RouterInfo (): m_Buffer (nullptr)
{
m_Addresses = boost::make_shared<Addresses>(); // create empty list
m_Addresses = AddressesPtr(new Addresses ()); // create empty list
}
RouterInfo::RouterInfo (const std::string& fullPath):
@ -48,7 +48,7 @@ namespace data
m_SupportedTransports (0),m_ReachableTransports (0), m_PublishedTransports (0),
m_Caps (0), m_Version (0), m_Congestion (eLowCongestion)
{
m_Addresses = boost::make_shared<Addresses>(); // create empty list
m_Addresses = AddressesPtr(new Addresses ()); // create empty list
m_Buffer = NewBuffer (); // always RouterInfo's
ReadFromFile (fullPath);
}
@ -60,7 +60,7 @@ namespace data
{
if (len <= MAX_RI_BUFFER_SIZE)
{
m_Addresses = boost::make_shared<Addresses>(); // create empty list
m_Addresses = AddressesPtr(new Addresses ()); // create empty list
m_Buffer = buf;
if (m_Buffer) m_Buffer->SetBufferLen (len);
ReadFromBuffer (true);
@ -439,10 +439,10 @@ namespace data
}
m_ReachableTransports |= m_PublishedTransports;
// update addresses
#if (BOOST_VERSION >= 105300)
#ifdef __cpp_lib_atomic_shared_ptr
m_Addresses = addresses;
#else
boost::atomic_store (&m_Addresses, addresses);
#else
m_Addresses = addresses; // race condition
#endif
// read peers
uint8_t numPeers;
@ -692,12 +692,12 @@ namespace data
if (addr->IsV4 ())
{
m_SupportedTransports |= eNTCP2V4;
(*m_Addresses)[eNTCP2V4Idx] = addr;
(*GetAddresses ())[eNTCP2V4Idx] = addr;
}
if (addr->IsV6 ())
{
m_SupportedTransports |= eNTCP2V6;
(*m_Addresses)[eNTCP2V6Idx] = addr;
(*GetAddresses ())[eNTCP2V6Idx] = addr;
}
}
@ -718,11 +718,12 @@ namespace data
if (host.is_v4 ()) addr->caps |= eV4;
if (host.is_v6 ()) addr->caps |= eV6;
}
auto addresses = GetAddresses ();
if (addr->IsV4 ())
{
m_SupportedTransports |= eNTCP2V4;
m_ReachableTransports |= eNTCP2V4;
(*m_Addresses)[eNTCP2V4Idx] = addr;
(*addresses)[eNTCP2V4Idx] = addr;
}
if (addr->IsV6 ())
{
@ -730,30 +731,31 @@ namespace data
{
m_SupportedTransports |= eNTCP2V6Mesh;
m_ReachableTransports |= eNTCP2V6Mesh;
(*m_Addresses)[eNTCP2V6MeshIdx] = addr;
(*addresses)[eNTCP2V6MeshIdx] = addr;
}
else
{
m_SupportedTransports |= eNTCP2V6;
m_ReachableTransports |= eNTCP2V6;
(*m_Addresses)[eNTCP2V6Idx] = addr;
(*addresses)[eNTCP2V6Idx] = addr;
}
}
}
void RouterInfo::RemoveNTCP2Address (bool v4)
{
auto addresses = GetAddresses ();
if (v4)
{
if ((*m_Addresses)[eNTCP2V6Idx])
(*m_Addresses)[eNTCP2V6Idx]->caps &= ~AddressCaps::eV4;
(*m_Addresses)[eNTCP2V4Idx].reset ();
if ((*addresses)[eNTCP2V6Idx])
(*addresses)[eNTCP2V6Idx]->caps &= ~AddressCaps::eV4;
(*addresses)[eNTCP2V4Idx].reset ();
}
else
{
if ((*m_Addresses)[eNTCP2V4Idx])
(*m_Addresses)[eNTCP2V4Idx]->caps &= ~AddressCaps::eV6;
(*m_Addresses)[eNTCP2V6Idx].reset ();
if ((*addresses)[eNTCP2V4Idx])
(*addresses)[eNTCP2V4Idx]->caps &= ~AddressCaps::eV6;
(*addresses)[eNTCP2V6Idx].reset ();
}
UpdateSupportedTransports ();
}
@ -769,15 +771,16 @@ namespace data
addr->ssu->mtu = 0;
memcpy (addr->s, staticKey, 32);
memcpy (addr->i, introKey, 32);
auto addresses = GetAddresses ();
if (addr->IsV4 ())
{
m_SupportedTransports |= eSSU2V4;
(*m_Addresses)[eSSU2V4Idx] = addr;
(*addresses)[eSSU2V4Idx] = addr;
}
if (addr->IsV6 ())
{
m_SupportedTransports |= eSSU2V6;
(*m_Addresses)[eSSU2V6Idx] = addr;
(*addresses)[eSSU2V6Idx] = addr;
}
}
@ -802,33 +805,35 @@ namespace data
if (host.is_v4 ()) addr->caps |= eV4;
if (host.is_v6 ()) addr->caps |= eV6;
}
auto addresses = GetAddresses ();
if (addr->IsV4 ())
{
m_SupportedTransports |= eSSU2V4;
m_ReachableTransports |= eSSU2V4;
(*m_Addresses)[eSSU2V4Idx] = addr;
(*addresses)[eSSU2V4Idx] = addr;
}
if (addr->IsV6 ())
{
m_SupportedTransports |= eSSU2V6;
m_ReachableTransports |= eSSU2V6;
(*m_Addresses)[eSSU2V6Idx] = addr;
(*addresses)[eSSU2V6Idx] = addr;
}
}
void RouterInfo::RemoveSSU2Address (bool v4)
{
auto addresses = GetAddresses ();
if (v4)
{
if ((*m_Addresses)[eSSU2V6Idx])
(*m_Addresses)[eSSU2V6Idx]->caps &= ~AddressCaps::eV4;
(*m_Addresses)[eSSU2V4Idx].reset ();
if ((*addresses)[eSSU2V6Idx])
(*addresses)[eSSU2V6Idx]->caps &= ~AddressCaps::eV4;
(*addresses)[eSSU2V4Idx].reset ();
}
else
{
if ((*m_Addresses)[eSSU2V4Idx])
(*m_Addresses)[eSSU2V4Idx]->caps &= ~AddressCaps::eV6;
(*m_Addresses)[eSSU2V6Idx].reset ();
if ((*addresses)[eSSU2V4Idx])
(*addresses)[eSSU2V4Idx]->caps &= ~AddressCaps::eV6;
(*addresses)[eSSU2V6Idx].reset ();
}
UpdateSupportedTransports ();
}
@ -869,17 +874,18 @@ namespace data
{
if (IsV6 ())
{
if ((*m_Addresses)[eNTCP2V6Idx])
auto addresses = GetAddresses ();
if ((*addresses)[eNTCP2V6Idx])
{
if ((*m_Addresses)[eNTCP2V6Idx]->IsV4 () && (*m_Addresses)[eNTCP2V4Idx])
(*m_Addresses)[eNTCP2V4Idx]->caps &= ~AddressCaps::eV6;
(*m_Addresses)[eNTCP2V6Idx].reset ();
if ((*addresses)[eNTCP2V6Idx]->IsV4 () && (*addresses)[eNTCP2V4Idx])
(*addresses)[eNTCP2V4Idx]->caps &= ~AddressCaps::eV6;
(*addresses)[eNTCP2V6Idx].reset ();
}
if ((*m_Addresses)[eSSU2V6Idx])
if ((*addresses)[eSSU2V6Idx])
{
if ((*m_Addresses)[eSSU2V6Idx]->IsV4 () && (*m_Addresses)[eSSU2V4Idx])
(*m_Addresses)[eSSU2V4Idx]->caps &= ~AddressCaps::eV6;
(*m_Addresses)[eSSU2V6Idx].reset ();
if ((*addresses)[eSSU2V6Idx]->IsV4 () && (*addresses)[eSSU2V4Idx])
(*addresses)[eSSU2V4Idx]->caps &= ~AddressCaps::eV6;
(*addresses)[eSSU2V6Idx].reset ();
}
UpdateSupportedTransports ();
}
@ -889,17 +895,18 @@ namespace data
{
if (IsV4 ())
{
if ((*m_Addresses)[eNTCP2V4Idx])
auto addresses = GetAddresses ();
if ((*addresses)[eNTCP2V4Idx])
{
if ((*m_Addresses)[eNTCP2V4Idx]->IsV6 () && (*m_Addresses)[eNTCP2V6Idx])
(*m_Addresses)[eNTCP2V6Idx]->caps &= ~AddressCaps::eV4;
(*m_Addresses)[eNTCP2V4Idx].reset ();
if ((*addresses)[eNTCP2V4Idx]->IsV6 () && (*addresses)[eNTCP2V6Idx])
(*addresses)[eNTCP2V6Idx]->caps &= ~AddressCaps::eV4;
(*addresses)[eNTCP2V4Idx].reset ();
}
if ((*m_Addresses)[eSSU2V4Idx])
if ((*addresses)[eSSU2V4Idx])
{
if ((*m_Addresses)[eSSU2V4Idx]->IsV6 () && (*m_Addresses)[eSSU2V6Idx])
(*m_Addresses)[eSSU2V6Idx]->caps &= ~AddressCaps::eV4;
(*m_Addresses)[eSSU2V4Idx].reset ();
if ((*addresses)[eSSU2V4Idx]->IsV6 () && (*addresses)[eSSU2V6Idx])
(*addresses)[eSSU2V6Idx]->caps &= ~AddressCaps::eV4;
(*addresses)[eSSU2V4Idx].reset ();
}
UpdateSupportedTransports ();
}
@ -920,7 +927,7 @@ namespace data
{
m_SupportedTransports &= ~eNTCP2V6Mesh;
m_ReachableTransports &= ~eNTCP2V6Mesh;
(*m_Addresses)[eNTCP2V6MeshIdx].reset ();
(*GetAddresses ())[eNTCP2V6MeshIdx].reset ();
}
}
@ -949,12 +956,12 @@ namespace data
return nullptr;
}
boost::shared_ptr<RouterInfo::Addresses> RouterInfo::GetAddresses () const
RouterInfo::AddressesPtr RouterInfo::GetAddresses () const
{
#if (BOOST_VERSION >= 105300)
return boost::atomic_load (&m_Addresses);
#else
#ifdef __cpp_lib_atomic_shared_ptr
return m_Addresses;
#else
return boost::atomic_load (&m_Addresses);
#endif
}
@ -962,10 +969,10 @@ namespace data
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (Filter filter) const
{
// TODO: make it more generic using comparator
#if (BOOST_VERSION >= 105300)
#ifdef __cpp_lib_atomic_shared_ptr
AddressesPtr addresses = m_Addresses;
#else
auto addresses = boost::atomic_load (&m_Addresses);
#else
auto addresses = m_Addresses;
#endif
for (const auto& address : *addresses)
if (address && filter (address)) return address;
@ -1062,7 +1069,7 @@ namespace data
void RouterInfo::SetUnreachableAddressesTransportCaps (uint8_t transports)
{
for (auto& addr: *m_Addresses)
for (auto& addr: *GetAddresses ())
{
if (addr && !addr->published)
{
@ -1076,7 +1083,7 @@ namespace data
{
m_SupportedTransports = 0;
m_ReachableTransports = 0;
for (const auto& addr: *m_Addresses)
for (const auto& addr: *GetAddresses ())
{
if (!addr) continue;
uint8_t transports = 0;
@ -1151,7 +1158,7 @@ namespace data
return netdb.NewRouterInfoAddress ();
}
boost::shared_ptr<RouterInfo::Addresses> RouterInfo::NewAddresses () const
RouterInfo::AddressesPtr RouterInfo::NewAddresses () const
{
return netdb.NewRouterInfoAddresses ();
}
@ -1503,9 +1510,9 @@ namespace data
return std::make_shared<Address> ();
}
boost::shared_ptr<RouterInfo::Addresses> LocalRouterInfo::NewAddresses () const
RouterInfo::AddressesPtr LocalRouterInfo::NewAddresses () const
{
return boost::make_shared<Addresses> ();
return RouterInfo::AddressesPtr(new RouterInfo::Addresses ());
}
std::shared_ptr<IdentityEx> LocalRouterInfo::NewIdentity (const uint8_t * buf, size_t len) const

View File

@ -15,8 +15,11 @@
#include <vector>
#include <array>
#include <iostream>
#include <memory>
#include <boost/asio.hpp>
#ifndef __cpp_lib_atomic_shared_ptr
#include <boost/shared_ptr.hpp>
#endif
#include "Identity.h"
#include "Profiling.h"
#include "Family.h"
@ -199,7 +202,11 @@ namespace data
};
typedef std::array<std::shared_ptr<Address>, eNumTransports> Addresses;
#ifdef __cpp_lib_atomic_shared_ptr
typedef std::shared_ptr<Addresses> AddressesPtr;
#else
typedef boost::shared_ptr<Addresses> AddressesPtr;
#endif
RouterInfo (const std::string& fullPath);
RouterInfo (const RouterInfo& ) = default;
RouterInfo& operator=(const RouterInfo& ) = default;
@ -214,7 +221,7 @@ namespace data
int GetVersion () const { return m_Version; };
virtual void SetProperty (const std::string& key, const std::string& value) {};
virtual void ClearProperties () {};
boost::shared_ptr<Addresses> GetAddresses () const; // should be called for local RI only, otherwise must return shared_ptr
AddressesPtr GetAddresses () const; // should be called for local RI only, otherwise must return shared_ptr
std::shared_ptr<const Address> GetNTCP2V4Address () const;
std::shared_ptr<const Address> GetNTCP2V6Address () const;
std::shared_ptr<const Address> GetPublishedNTCP2V4Address () const;
@ -333,7 +340,7 @@ namespace data
std::shared_ptr<const Address> GetAddress (Filter filter) const;
virtual std::shared_ptr<Buffer> NewBuffer () const;
virtual std::shared_ptr<Address> NewAddress () const;
virtual boost::shared_ptr<Addresses> NewAddresses () const;
virtual AddressesPtr NewAddresses () const;
virtual std::shared_ptr<IdentityEx> NewIdentity (const uint8_t * buf, size_t len) const;
private:
@ -342,7 +349,11 @@ namespace data
std::shared_ptr<const IdentityEx> m_RouterIdentity;
std::shared_ptr<Buffer> m_Buffer;
uint64_t m_Timestamp; // in milliseconds
boost::shared_ptr<Addresses> m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9
#ifdef __cpp_lib_atomic_shared_ptr
std::atomic<AddressesPtr> m_Addresses;
#else
AddressesPtr m_Addresses;
#endif
bool m_IsUpdated, m_IsUnreachable, m_IsFloodfill;
CompatibleTransports m_SupportedTransports, m_ReachableTransports, m_PublishedTransports;
uint8_t m_Caps;
@ -377,7 +388,7 @@ namespace data
void WriteString (const std::string& str, std::ostream& s) const;
std::shared_ptr<Buffer> NewBuffer () const override;
std::shared_ptr<Address> NewAddress () const override;
boost::shared_ptr<Addresses> NewAddresses () const override;
RouterInfo::AddressesPtr NewAddresses () const override;
std::shared_ptr<IdentityEx> NewIdentity (const uint8_t * buf, size_t len) const override;
private: