AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
AsyncAcceptor Class Reference

#include "AsyncAcceptor.h"

Public Types

typedef void(* AcceptCallback) (IoContextTcpSocket &&newSocket, uint32 threadIndex)
 

Public Member Functions

 AsyncAcceptor (Acore::Asio::IoContext &ioContext, std::string const &bindIp, uint16 port, bool supportSocketActivation=false)
 
template<class T >
void AsyncAccept ()
 
template<AcceptCallback acceptCallback>
void AsyncAcceptWithCallback ()
 
bool Bind ()
 
void Close ()
 
void SetSocketFactory (std::function< std::pair< IoContextTcpSocket *, uint32 >()> func)
 

Private Member Functions

std::pair< IoContextTcpSocket *, uint32DefaultSocketFactory ()
 

Private Attributes

boost::asio::basic_socket_acceptor< boost::asio::ip::tcp, IoContextTcpSocket::executor_type > _acceptor
 
boost::asio::ip::tcp::endpoint _endpoint
 
IoContextTcpSocket _socket
 
std::atomic< bool > _closed
 
std::function< std::pair< IoContextTcpSocket *, uint32 >()> _socketFactory
 
bool _supportSocketActivation
 

Detailed Description

Member Typedef Documentation

◆ AcceptCallback

typedef void(* AsyncAcceptor::AcceptCallback) (IoContextTcpSocket &&newSocket, uint32 threadIndex)

Constructor & Destructor Documentation

◆ AsyncAcceptor()

AsyncAcceptor::AsyncAcceptor ( Acore::Asio::IoContext ioContext,
std::string const &  bindIp,
uint16  port,
bool  supportSocketActivation = false 
)
inline
38 :
39 _acceptor(ioContext), _endpoint(Acore::Net::make_address(bindIp), port),
40 _socket(ioContext), _closed(false), _socketFactory([this](){ return DefaultSocketFactory(); }),
41 _supportSocketActivation(supportSocketActivation)
42 {
43 int const listen_fd = get_listen_fd();
44 if (_supportSocketActivation && listen_fd > 0)
45 {
46 LOG_DEBUG("network", "Using socket from systemd socket activation");
47 boost::system::error_code errorCode;
48 _acceptor.assign(boost::asio::ip::tcp::v4(), listen_fd, errorCode);
49 if (errorCode)
50 LOG_WARN("network", "Failed to assign socket {}", errorCode.message());
51 }
52 }
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
#define LOG_WARN(filterType__,...)
Definition Log.h:162
int get_listen_fd()
Definition Systemd.cpp:55
std::function< std::pair< IoContextTcpSocket *, uint32 >()> _socketFactory
Definition AsyncAcceptor.h:142
std::atomic< bool > _closed
Definition AsyncAcceptor.h:141
boost::asio::ip::tcp::endpoint _endpoint
Definition AsyncAcceptor.h:139
IoContextTcpSocket _socket
Definition AsyncAcceptor.h:140
std::pair< IoContextTcpSocket *, uint32 > DefaultSocketFactory()
Definition AsyncAcceptor.h:136
boost::asio::basic_socket_acceptor< boost::asio::ip::tcp, IoContextTcpSocket::executor_type > _acceptor
Definition AsyncAcceptor.h:138
bool _supportSocketActivation
Definition AsyncAcceptor.h:143

References DefaultSocketFactory().

Member Function Documentation

◆ AsyncAccept()

template<class T >
void AsyncAcceptor::AsyncAccept ( )
148{
149 _acceptor.async_accept(_socket, [this](boost::system::error_code error)
150 {
151 if (!error)
152 {
153 try
154 {
155 // this-> is required here to fix an segmentation fault in gcc 4.7.2 - reason is lambdas in a templated class
156 std::make_shared<T>(std::move(this->_socket))->Start();
157 }
158 catch (boost::system::system_error const& err)
159 {
160 LOG_INFO("network", "Failed to retrieve client's remote address {}", err.what());
161 }
162 }
163
164 // lets slap some more this-> on this so we can fix this bug with gcc 4.7.2 throwing internals in yo face
165 if (!_closed)
166 this->AsyncAccept<T>();
167 });
168}
#define LOG_INFO(filterType__,...)
Definition Log.h:166

References _acceptor, _closed, _socket, and LOG_INFO.

◆ AsyncAcceptWithCallback()

template<AcceptCallback acceptCallback>
void AsyncAcceptor::AsyncAcceptWithCallback ( )
inline
59 {
60 IoContextTcpSocket* socket;
61 uint32 threadIndex;
62 std::tie(socket, threadIndex) = _socketFactory();
63 _acceptor.async_accept(*socket, [this, socket, threadIndex](boost::system::error_code error)
64 {
65 if (!error)
66 {
67 try
68 {
69 socket->non_blocking(true);
70
71 acceptCallback(std::move(*socket), threadIndex);
72 }
73 catch (boost::system::system_error const& err)
74 {
75 LOG_INFO("network", "Failed to initialize client's socket {}", err.what());
76 }
77 }
78
79 if (!_closed)
80 this->AsyncAcceptWithCallback<acceptCallback>();
81 });
82 }
std::uint32_t uint32
Definition Define.h:107
boost::asio::basic_stream_socket< boost::asio::ip::tcp, boost::asio::io_context::executor_type > IoContextTcpSocket
Definition Socket.h:39

References _acceptor, _closed, _socketFactory, and LOG_INFO.

◆ Bind()

bool AsyncAcceptor::Bind ( )
inline
85 {
86 boost::system::error_code errorCode;
87 // with socket activation the acceptor is already open and bound
88 if (!_acceptor.is_open())
89 {
90 _acceptor.open(_endpoint.protocol(), errorCode);
91 if (errorCode)
92 {
93 LOG_INFO("network", "Failed to open acceptor {}", errorCode.message());
94 return false;
95 }
96
97#if AC_PLATFORM != AC_PLATFORM_WINDOWS
98 _acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true), errorCode);
99 if (errorCode)
100 {
101 LOG_INFO("network", "Failed to set reuse_address option on acceptor {}", errorCode.message());
102 return false;
103 }
104#endif
105
106 _acceptor.bind(_endpoint, errorCode);
107 if (errorCode)
108 {
109 LOG_INFO("network", "Could not bind to {}:{} {}", _endpoint.address().to_string(), _endpoint.port(), errorCode.message());
110 return false;
111 }
112 }
113
114 _acceptor.listen(ACORE_MAX_LISTEN_CONNECTIONS, errorCode);
115 if (errorCode)
116 {
117 LOG_INFO("network", "Failed to start listening on {}:{} {}", _endpoint.address().to_string(), _endpoint.port(), errorCode.message());
118 return false;
119 }
120
121 return true;
122 }
constexpr auto ACORE_MAX_LISTEN_CONNECTIONS
Definition AsyncAcceptor.h:31

References _acceptor, _endpoint, ACORE_MAX_LISTEN_CONNECTIONS, and LOG_INFO.

◆ Close()

void AsyncAcceptor::Close ( )
inline
125 {
126 if (_closed.exchange(true))
127 return;
128
129 boost::system::error_code err;
130 _acceptor.close(err);
131 }

References _acceptor, and _closed.

◆ DefaultSocketFactory()

std::pair< IoContextTcpSocket *, uint32 > AsyncAcceptor::DefaultSocketFactory ( )
inlineprivate
136{ return std::make_pair(&_socket, 0); }

References _socket.

Referenced by AsyncAcceptor().

◆ SetSocketFactory()

void AsyncAcceptor::SetSocketFactory ( std::function< std::pair< IoContextTcpSocket *, uint32 >()>  func)
inline
133{ _socketFactory = std::move(func); }

References _socketFactory.

Member Data Documentation

◆ _acceptor

boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, IoContextTcpSocket::executor_type> AsyncAcceptor::_acceptor
private

◆ _closed

std::atomic<bool> AsyncAcceptor::_closed
private

◆ _endpoint

boost::asio::ip::tcp::endpoint AsyncAcceptor::_endpoint
private

Referenced by Bind().

◆ _socket

IoContextTcpSocket AsyncAcceptor::_socket
private

◆ _socketFactory

std::function<std::pair<IoContextTcpSocket*, uint32>()> AsyncAcceptor::_socketFactory
private

◆ _supportSocketActivation

bool AsyncAcceptor::_supportSocketActivation
private

The documentation for this class was generated from the following file: