diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 835c8e52..5240cb05 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -823,7 +823,7 @@ namespace client } ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - RunnableService ("Destination"), LeaseSetDestination (GetService (), isPublic, params), + RunnableService ("Destination"), LeaseSetDestination (GetIOService (), isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(GetService()) @@ -905,7 +905,7 @@ namespace client m_StreamingDestination->Start (); for (auto& it: m_StreamingDestinationsByPorts) it.second->Start (); - StartService (); + StartIOService (); } } @@ -929,7 +929,7 @@ namespace client delete m_DatagramDestination; m_DatagramDestination = nullptr; } - StopService (); + StopIOService (); } } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 5b411c14..529a9adb 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -102,6 +102,7 @@ namespace client LeaseSetDestination (boost::asio::io_service& service, bool isPublic, const std::map * params = nullptr); ~LeaseSetDestination (); const std::string& GetNickname () const { return m_Nickname; }; + boost::asio::io_service& GetService () { return m_Service; }; virtual void Start (); virtual void Stop (); @@ -191,7 +192,7 @@ namespace client bool IsPerClientAuth () const { return m_AuthType > 0; }; }; - class ClientDestination: public i2p::util::RunnableService, public LeaseSetDestination + class ClientDestination: private i2p::util::RunnableService, public LeaseSetDestination { public: #ifdef I2LUA diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index e79be97a..034f7e21 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1155,7 +1155,7 @@ namespace transport { if (!IsRunning ()) { - StartService (); + StartIOService (); auto& addresses = context.GetRouterInfo ().GetAddresses (); for (const auto& address: addresses) { @@ -1217,7 +1217,7 @@ namespace transport if (IsRunning ()) m_TerminationTimer.cancel (); - StopService (); + StopIOService (); } bool NTCP2Server::AddNTCP2Session (std::shared_ptr session, bool incoming) diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index a63b86b8..7e3c53e8 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -216,7 +216,7 @@ namespace transport std::list > m_SendQueue; }; - class NTCP2Server: public i2p::util::RunnableServiceWithWork + class NTCP2Server: private i2p::util::RunnableServiceWithWork { public: @@ -225,6 +225,7 @@ namespace transport void Start (); void Stop (); + boost::asio::io_service& GetService () { return GetIOService (); }; bool AddNTCP2Session (std::shared_ptr session, bool incoming = false); void RemoveNTCP2Session (std::shared_ptr session); diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 6ae9fa6b..051eea5d 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -58,7 +58,7 @@ namespace i2p namespace util { - void RunnableService::StartService () + void RunnableService::StartIOService () { if (!m_IsRunning) { @@ -67,7 +67,7 @@ namespace util } } - void RunnableService::StopService () + void RunnableService::StopIOService () { if (m_IsRunning) { @@ -245,10 +245,10 @@ namespace net #else std::string localAddressUniversal = localAddress.to_string(); #endif - - typedef int (* IPN)(int af, const char *src, void *dst); + + typedef int (* IPN)(int af, const char *src, void *dst); IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton"); - if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found + if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found if(localAddress.is_v4()) { diff --git a/libi2pd/util.h b/libi2pd/util.h index febb98b0..2202ccd9 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -125,16 +125,16 @@ namespace util class RunnableService { - public: + protected: RunnableService (const std::string& name): m_Name (name), m_IsRunning (false) {} virtual ~RunnableService () {} - boost::asio::io_service& GetService () { return m_Service; } + boost::asio::io_service& GetIOService () { return m_Service; } bool IsRunning () const { return m_IsRunning; }; - void StartService (); - void StopService (); + void StartIOService (); + void StopIOService (); private: @@ -150,10 +150,10 @@ namespace util class RunnableServiceWithWork: public RunnableService { - public: + protected: RunnableServiceWithWork (const std::string& name): - RunnableService (name), m_Work (GetService ()) {} + RunnableService (name), m_Work (GetIOService ()) {} private: diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index aba090dc..c7bbdb46 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -743,8 +743,8 @@ namespace client } BOBCommandChannel::BOBCommandChannel (const std::string& address, int port): - m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)) + RunnableService ("BOB"), + m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)) { // command -> handler m_CommandHandlers[BOB_COMMAND_ZAP] = &BOBCommandSession::ZapCommandHandler; @@ -794,7 +794,8 @@ namespace client BOBCommandChannel::~BOBCommandChannel () { - Stop (); + if (IsRunning ()) + Stop (); for (const auto& it: m_Destinations) delete it.second; } @@ -802,38 +803,15 @@ namespace client void BOBCommandChannel::Start () { Accept (); - m_IsRunning = true; - m_Thread = new std::thread (std::bind (&BOBCommandChannel::Run, this)); + StartIOService (); } void BOBCommandChannel::Stop () { - m_IsRunning = false; for (auto& it: m_Destinations) it.second->Stop (); m_Acceptor.cancel (); - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = nullptr; - } - } - - void BOBCommandChannel::Run () - { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "BOB: runtime exception: ", ex.what ()); - } - } + StopIOService (); } void BOBCommandChannel::AddDestination (const std::string& name, BOBDestination * dest) diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index 8f1af185..15a0afaf 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -7,6 +7,7 @@ #include #include #include +#include "util.h" #include "I2PTunnel.h" #include "I2PService.h" #include "Identity.h" @@ -231,7 +232,7 @@ namespace client }; typedef void (BOBCommandSession::*BOBCommandHandler)(const char * operand, size_t len); - class BOBCommandChannel + class BOBCommandChannel: private i2p::util::RunnableService { public: @@ -241,22 +242,18 @@ namespace client void Start (); void Stop (); - boost::asio::io_service& GetService () { return m_Service; }; + boost::asio::io_service& GetService () { return GetIOService (); }; void AddDestination (const std::string& name, BOBDestination * dest); void DeleteDestination (const std::string& name); BOBDestination * FindDestination (const std::string& name); private: - void Run (); void Accept (); void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr session); private: - bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; boost::asio::ip::tcp::acceptor m_Acceptor; std::map m_Destinations; std::map m_CommandHandlers; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index d14491b2..53e740b3 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -344,8 +344,7 @@ namespace client if (it != m_Destinations.end ()) { LogPrint (eLogWarning, "Clients: Local destination ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " exists"); - if (!it->second->IsRunning ()) - it->second->Start (); + it->second->Start (); // make sure to start return it->second; } auto localDestination = std::make_shared (keys, isPublic, params); diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index e06b2db4..69b26cab 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -24,7 +24,7 @@ namespace client { I2CPDestination::I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params): - RunnableService ("I2CP"), LeaseSetDestination (GetService (), isPublic, ¶ms), + RunnableService ("I2CP"), LeaseSetDestination (GetIOService (), isPublic, ¶ms), m_Owner (owner), m_Identity (identity) { } @@ -40,7 +40,7 @@ namespace client if (!IsRunning ()) { LeaseSetDestination::Start (); - StartService (); + StartIOService (); } } @@ -49,7 +49,7 @@ namespace client if (IsRunning ()) { LeaseSetDestination::Stop (); - StopService (); + StopIOService (); } } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index a51597af..d4e05b51 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -62,7 +62,7 @@ namespace client const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability"; class I2CPSession; - class I2CPDestination: public i2p::util::RunnableService, public LeaseSetDestination + class I2CPDestination: private i2p::util::RunnableService, public LeaseSetDestination { public: diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 766a1940..3ddfc940 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1001,9 +1001,9 @@ namespace client } SAMBridge::SAMBridge (const std::string& address, int port): - m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), - m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (m_Service, m_DatagramEndpoint), + RunnableService ("SAM"), + m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), + m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), m_SignatureTypes { {"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1}, @@ -1020,7 +1020,7 @@ namespace client SAMBridge::~SAMBridge () { - if (m_IsRunning) + if (IsRunning ()) Stop (); } @@ -1028,14 +1028,11 @@ namespace client { Accept (); ReceiveDatagram (); - m_IsRunning = true; - m_Thread = new std::thread (std::bind (&SAMBridge::Run, this)); + StartIOService (); } void SAMBridge::Stop () { - m_IsRunning = false; - try { m_Acceptor.cancel (); @@ -1048,28 +1045,7 @@ namespace client for (auto& it: m_Sessions) it.second->CloseStreams (); m_Sessions.clear (); - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = nullptr; - } - } - - void SAMBridge::Run () - { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "SAM: runtime exception: ", ex.what ()); - } - } + StopIOService (); } void SAMBridge::Accept () diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index aebdccb6..029f3524 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -9,6 +9,7 @@ #include #include #include +#include "util.h" #include "Identity.h" #include "LeaseSet.h" #include "Streaming.h" @@ -174,7 +175,7 @@ namespace client void CloseStreams (); }; - class SAMBridge + class SAMBridge: private i2p::util::RunnableService { public: @@ -184,7 +185,7 @@ namespace client void Start (); void Stop (); - boost::asio::io_service& GetService () { return m_Service; }; + boost::asio::io_service& GetService () { return GetIOService (); }; std::shared_ptr CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient const std::map * params); void CloseSession (const std::string& id); @@ -201,8 +202,6 @@ namespace client private: - void Run (); - void Accept (); void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket); @@ -211,9 +210,6 @@ namespace client private: - bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; boost::asio::ip::tcp::acceptor m_Acceptor; boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint; boost::asio::ip::udp::socket m_DatagramSocket;