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

pull/2101/head
orignal 1 month ago
parent ba451eeca5
commit cd648b9b3f

@ -127,12 +127,12 @@ namespace data
} }
bool PopulateRouterInfoBuffer (std::shared_ptr<RouterInfo> r); bool PopulateRouterInfoBuffer (std::shared_ptr<RouterInfo> r);
std::shared_ptr<RouterInfo::Address> NewRouterInfoAddress () { return m_RouterInfoAddressesPool.AcquireSharedMt (); }; 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 *)> std::bind <void (i2p::util::MemoryPoolMt<RouterInfo::Addresses>::*)(RouterInfo::Addresses *)>
(&i2p::util::MemoryPoolMt<RouterInfo::Addresses>::ReleaseMt, (&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<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); }; std::shared_ptr<IdentityEx> NewIdentity (const uint8_t * buf, size_t len) { return m_IdentitiesPool.AcquireSharedMt (buf, len); };

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

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

Loading…
Cancel
Save