mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 09:17:18 +00:00
feat(Core/Common): add Asio network threading (#6063)
This commit is contained in:
44
src/common/Asio/AsioHacksFwd.h
Normal file
44
src/common/Asio/AsioHacksFwd.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
*/
|
||||
|
||||
#ifndef AsioHacksFwd_h__
|
||||
#define AsioHacksFwd_h__
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
/**
|
||||
Collection of forward declarations to improve compile time
|
||||
*/
|
||||
namespace boost::posix_time
|
||||
{
|
||||
class ptime;
|
||||
}
|
||||
|
||||
namespace boost::asio
|
||||
{
|
||||
template <typename Time>
|
||||
struct time_traits;
|
||||
}
|
||||
|
||||
namespace boost::asio::ip
|
||||
{
|
||||
class address;
|
||||
class tcp;
|
||||
|
||||
template <typename InternetProtocol>
|
||||
class basic_endpoint;
|
||||
|
||||
typedef basic_endpoint<tcp> tcp_endpoint;
|
||||
}
|
||||
|
||||
namespace acore::Asio
|
||||
{
|
||||
class DeadlineTimer;
|
||||
class IoContext;
|
||||
class Resolver;
|
||||
class Strand;
|
||||
}
|
||||
|
||||
#endif // AsioHacksFwd_h__
|
||||
30
src/common/Asio/DeadlineTimer.h
Normal file
30
src/common/Asio/DeadlineTimer.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
*/
|
||||
|
||||
#ifndef DeadlineTimer_h__
|
||||
#define DeadlineTimer_h__
|
||||
|
||||
#include <boost/asio/deadline_timer.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 107000
|
||||
#define BasicDeadlineTimerThirdTemplateArg , boost::asio::io_context::executor_type
|
||||
#elif BOOST_VERSION >= 106600
|
||||
#define BasicDeadlineTimerThirdTemplateArg
|
||||
#else
|
||||
#define BasicDeadlineTimerThirdTemplateArg , boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime>>
|
||||
#endif
|
||||
|
||||
#define DeadlineTimerBase boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> BasicDeadlineTimerThirdTemplateArg>
|
||||
|
||||
namespace acore::Asio
|
||||
{
|
||||
class DeadlineTimer : public DeadlineTimerBase
|
||||
{
|
||||
public:
|
||||
using DeadlineTimerBase::basic_deadline_timer;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DeadlineTimer_h__
|
||||
65
src/common/Asio/IoContext.h
Normal file
65
src/common/Asio/IoContext.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
*/
|
||||
|
||||
#ifndef IoContext_h__
|
||||
#define IoContext_h__
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 106600
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#define IoContextBaseNamespace boost::asio
|
||||
#define IoContextBase io_context
|
||||
#else
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#define IoContextBaseNamespace boost::asio
|
||||
#define IoContextBase io_service
|
||||
#endif
|
||||
|
||||
namespace acore::Asio
|
||||
{
|
||||
class IoContext
|
||||
{
|
||||
public:
|
||||
IoContext() : _impl() { }
|
||||
explicit IoContext(int concurrency_hint) : _impl(concurrency_hint) { }
|
||||
|
||||
operator IoContextBaseNamespace::IoContextBase&() { return _impl; }
|
||||
operator IoContextBaseNamespace::IoContextBase const&() const { return _impl; }
|
||||
|
||||
std::size_t run() { return _impl.run(); }
|
||||
void stop() { _impl.stop(); }
|
||||
|
||||
#if BOOST_VERSION >= 106600
|
||||
boost::asio::io_context::executor_type get_executor() noexcept { return _impl.get_executor(); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
IoContextBaseNamespace::IoContextBase _impl;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline decltype(auto) post(IoContextBaseNamespace::IoContextBase& ioContext, T&& t)
|
||||
{
|
||||
#if BOOST_VERSION >= 106600
|
||||
return boost::asio::post(ioContext, std::forward<T>(t));
|
||||
#else
|
||||
return ioContext.post(std::forward<T>(t));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline decltype(auto) get_io_context(T&& ioObject)
|
||||
{
|
||||
#if BOOST_VERSION >= 106600
|
||||
return ioObject.get_executor().context();
|
||||
#else
|
||||
return ioObject.get_io_service();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // IoContext_h__
|
||||
31
src/common/Asio/IpAddress.h
Normal file
31
src/common/Asio/IpAddress.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
*/
|
||||
|
||||
#ifndef IpAddress_h__
|
||||
#define IpAddress_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
|
||||
namespace acore::Net
|
||||
{
|
||||
#if BOOST_VERSION >= 106600
|
||||
using boost::asio::ip::make_address;
|
||||
using boost::asio::ip::make_address_v4;
|
||||
inline uint32 address_to_uint(boost::asio::ip::address_v4 const& address) { return address.to_uint(); }
|
||||
#else
|
||||
inline boost::asio::ip::address make_address(char const* str) { return boost::asio::ip::address::from_string(str); }
|
||||
inline boost::asio::ip::address make_address(char const* str, boost::system::error_code& ec) { return boost::asio::ip::address::from_string(str, ec); }
|
||||
inline boost::asio::ip::address make_address(std::string const& str) { return boost::asio::ip::address::from_string(str); }
|
||||
inline boost::asio::ip::address make_address(std::string const& str, boost::system::error_code& ec) { return boost::asio::ip::address::from_string(str, ec); }
|
||||
inline boost::asio::ip::address_v4 make_address_v4(char const* str) { return boost::asio::ip::address_v4::from_string(str); }
|
||||
inline boost::asio::ip::address_v4 make_address_v4(char const* str, boost::system::error_code& ec) { return boost::asio::ip::address_v4::from_string(str, ec); }
|
||||
inline boost::asio::ip::address_v4 make_address_v4(std::string const& str) { return boost::asio::ip::address_v4::from_string(str); }
|
||||
inline boost::asio::ip::address_v4 make_address_v4(std::string const& str, boost::system::error_code& ec) { return boost::asio::ip::address_v4::from_string(str, ec); }
|
||||
inline uint32 address_to_uint(boost::asio::ip::address_v4 const& address) { return address.to_ulong(); }
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // IpAddress_h__
|
||||
57
src/common/Asio/IpNetwork.h
Normal file
57
src/common/Asio/IpNetwork.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
*/
|
||||
|
||||
#ifndef IpNetwork_h__
|
||||
#define IpNetwork_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include "IpAddress.h"
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 106600
|
||||
#include <boost/asio/ip/network_v4.hpp>
|
||||
#include <boost/asio/ip/network_v6.hpp>
|
||||
#endif
|
||||
|
||||
namespace acore::Net
|
||||
{
|
||||
inline bool IsInNetwork(boost::asio::ip::address_v4 const& networkAddress, boost::asio::ip::address_v4 const& mask, boost::asio::ip::address_v4 const& clientAddress)
|
||||
{
|
||||
#if BOOST_VERSION >= 106600
|
||||
boost::asio::ip::network_v4 network = boost::asio::ip::make_network_v4(networkAddress, mask);
|
||||
boost::asio::ip::address_v4_range hosts = network.hosts();
|
||||
return hosts.find(clientAddress) != hosts.end();
|
||||
#else
|
||||
return (clientAddress.to_ulong() & mask.to_ulong()) == (networkAddress.to_ulong() & mask.to_ulong());
|
||||
#endif
|
||||
}
|
||||
|
||||
inline boost::asio::ip::address_v4 GetDefaultNetmaskV4(boost::asio::ip::address_v4 const& networkAddress)
|
||||
{
|
||||
if ((address_to_uint(networkAddress) & 0x80000000) == 0)
|
||||
return boost::asio::ip::address_v4(0xFF000000);
|
||||
if ((address_to_uint(networkAddress) & 0xC0000000) == 0x80000000)
|
||||
return boost::asio::ip::address_v4(0xFFFF0000);
|
||||
if ((address_to_uint(networkAddress) & 0xE0000000) == 0xC0000000)
|
||||
return boost::asio::ip::address_v4(0xFFFFFF00);
|
||||
return boost::asio::ip::address_v4(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
inline bool IsInNetwork(boost::asio::ip::address_v6 const& networkAddress, uint16 prefixLength, boost::asio::ip::address_v6 const& clientAddress)
|
||||
{
|
||||
#if BOOST_VERSION >= 106600
|
||||
boost::asio::ip::network_v6 network = boost::asio::ip::make_network_v6(networkAddress, prefixLength);
|
||||
boost::asio::ip::address_v6_range hosts = network.hosts();
|
||||
return hosts.find(clientAddress) != hosts.end();
|
||||
#else
|
||||
(void)networkAddress;
|
||||
(void)prefixLength;
|
||||
(void)clientAddress;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // IpNetwork_h__
|
||||
51
src/common/Asio/Resolver.h
Normal file
51
src/common/Asio/Resolver.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
*/
|
||||
|
||||
#ifndef Resolver_h__
|
||||
#define Resolver_h__
|
||||
|
||||
#include "IoContext.h"
|
||||
#include "Optional.h"
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace acore::Asio
|
||||
{
|
||||
/**
|
||||
Hack to make it possible to forward declare resolver (one of its template arguments is a typedef to something super long and using nested classes)
|
||||
*/
|
||||
class Resolver
|
||||
{
|
||||
public:
|
||||
explicit Resolver(IoContext& ioContext) : _impl(ioContext) { }
|
||||
|
||||
Optional<boost::asio::ip::tcp::endpoint> Resolve(boost::asio::ip::tcp const& protocol, std::string const& host, std::string const& service)
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
#if BOOST_VERSION >= 106600
|
||||
boost::asio::ip::resolver_base::flags flagsResolver = boost::asio::ip::resolver_base::all_matching;
|
||||
boost::asio::ip::tcp::resolver::results_type results = _impl.resolve(protocol, host, service, flagsResolver, ec);
|
||||
if (results.begin() == results.end() || ec)
|
||||
return {};
|
||||
|
||||
return results.begin()->endpoint();
|
||||
#else
|
||||
boost::asio::ip::resolver_query_base::flags flagsQuery = boost::asio::ip::tcp::resolver::query::all_matching;
|
||||
boost::asio::ip::tcp::resolver::query query(std::move(protocol), std::move(host), std::move(service), flagsQuery);
|
||||
boost::asio::ip::tcp::resolver::iterator itr = _impl.resolve(query, ec);
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
if (itr == end || ec)
|
||||
return {};
|
||||
|
||||
return itr->endpoint();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
boost::asio::ip::tcp::resolver _impl;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // Resolver_h__
|
||||
38
src/common/Asio/Strand.h
Normal file
38
src/common/Asio/Strand.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
*/
|
||||
|
||||
#ifndef Strand_h__
|
||||
#define Strand_h__
|
||||
|
||||
#include "IoContext.h"
|
||||
#include <boost/asio/strand.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 106600
|
||||
#include <boost/asio/bind_executor.hpp>
|
||||
#endif
|
||||
|
||||
namespace acore::Asio
|
||||
{
|
||||
/**
|
||||
Hack to make it possible to forward declare strand (which is a inner class)
|
||||
*/
|
||||
class Strand : public IoContextBaseNamespace::IoContextBase::strand
|
||||
{
|
||||
public:
|
||||
Strand(IoContext& ioContext) : IoContextBaseNamespace::IoContextBase::strand(ioContext) { }
|
||||
};
|
||||
|
||||
#if BOOST_VERSION >= 106600
|
||||
using boost::asio::bind_executor;
|
||||
#else
|
||||
template<typename T>
|
||||
inline decltype(auto) bind_executor(Strand& strand, T&& t)
|
||||
{
|
||||
return strand.wrap(std::forward<T>(t));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // Strand_h__
|
||||
Reference in New Issue
Block a user