TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
AsyncAcceptor.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef __ASYNCACCEPT_H_
19 #define __ASYNCACCEPT_H_
20 
21 #include "Log.h"
22 #include <boost/asio.hpp>
23 #include <functional>
24 #include <atomic>
25 
26 using boost::asio::ip::tcp;
27 
29 {
30 public:
31  typedef void(*AcceptCallback)(tcp::socket&& newSocket, uint32 threadIndex);
32 
33  AsyncAcceptor(boost::asio::io_service& ioService, std::string const& bindIp, uint16 port) :
34  _acceptor(ioService, tcp::endpoint(boost::asio::ip::address::from_string(bindIp), port)),
36  {
37  }
38 
39  template<class T>
40  void AsyncAccept();
41 
42  template<AcceptCallback acceptCallback>
44  {
45  tcp::socket* socket;
46  uint32 threadIndex;
47  std::tie(socket, threadIndex) = _socketFactory();
48  _acceptor.async_accept(*socket, [this, socket, threadIndex](boost::system::error_code error)
49  {
50  if (!error)
51  {
52  try
53  {
54  socket->non_blocking(true);
55 
56  acceptCallback(std::move(*socket), threadIndex);
57  }
58  catch (boost::system::system_error const& err)
59  {
60  TC_LOG_INFO("network", "Failed to initialize client's socket %s", err.what());
61  }
62  }
63 
64  if (!_closed)
65  this->AsyncAcceptWithCallback<acceptCallback>();
66  });
67  }
68 
69  void Close()
70  {
71  if (_closed.exchange(true))
72  return;
73 
74  boost::system::error_code err;
75  _acceptor.close(err);
76  }
77 
78  void SetSocketFactory(std::function<std::pair<tcp::socket*, uint32>()> func) { _socketFactory = func; }
79 
80 private:
81  std::pair<tcp::socket*, uint32> DefeaultSocketFactory() { return std::make_pair(&_socket, 0); }
82 
83  tcp::acceptor _acceptor;
84  tcp::socket _socket;
85  std::atomic<bool> _closed;
86  std::function<std::pair<tcp::socket*, uint32>()> _socketFactory;
87 };
88 
89 template<class T>
91 {
92  _acceptor.async_accept(_socket, [this](boost::system::error_code error)
93  {
94  if (!error)
95  {
96  try
97  {
98  // this-> is required here to fix an segmentation fault in gcc 4.7.2 - reason is lambdas in a templated class
99  std::make_shared<T>(std::move(this->_socket))->Start();
100  }
101  catch (boost::system::system_error const& err)
102  {
103  TC_LOG_INFO("network", "Failed to retrieve client's remote address %s", err.what());
104  }
105  }
106 
107  // lets slap some more this-> on this so we can fix this bug with gcc 4.7.2 throwing internals in yo face
108  if (!_closed)
109  this->AsyncAccept<T>();
110  });
111 }
112 
113 #endif /* __ASYNCACCEPT_H_ */
Definition: AsyncAcceptor.h:28
std::function< std::pair< tcp::socket *, uint32 >)> _socketFactory
Definition: AsyncAcceptor.h:86
void Close()
Definition: AsyncAcceptor.h:69
Definition: SFMT.h:153
tcp::socket _socket
Definition: AsyncAcceptor.h:84
STL namespace.
#define false
Definition: CascPort.h:18
tcp::acceptor _acceptor
Definition: AsyncAcceptor.h:83
void SetSocketFactory(std::function< std::pair< tcp::socket *, uint32 >()> func)
Definition: AsyncAcceptor.h:78
uint32_t uint32
Definition: Define.h:150
uint16_t uint16
Definition: Define.h:151
AsyncAcceptor(boost::asio::io_service &ioService, std::string const &bindIp, uint16 port)
Definition: AsyncAcceptor.h:33
void AsyncAcceptWithCallback()
Definition: AsyncAcceptor.h:43
std::pair< tcp::socket *, uint32 > DefeaultSocketFactory()
Definition: AsyncAcceptor.h:81
void AsyncAccept()
Definition: AsyncAcceptor.h:90
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:201
void(* AcceptCallback)(tcp::socket &&newSocket, uint32 threadIndex)
Definition: AsyncAcceptor.h:31
std::atomic< bool > _closed
Definition: AsyncAcceptor.h:85